poj2750 PottedFlower(线段树的环状操作)
生活随笔
收集整理的這篇文章主要介紹了
poj2750 PottedFlower(线段树的环状操作)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目:Potted Flower
大意:該你一個換環,求環上的最大連續的和(如果最大和包含所有數,要求減去最小的一個)。
思路:這道題的思路并不難,需要在線段樹里維護區間的最大和,最小和(應為是環狀的,所以答案有可能是總和減去最小和),然后需要用一個區間左邊的最大最小,右邊的最大最小來維護區間的最大和最小和。這道題的解法就是這樣。
代碼奉上
#include<cstdio> #include<algorithm> using namespace std; #define M(i) ((t[(i)].l + t[i].r) >> 1) const int MAXN = 1e5 + 5; const int INF = 1e9; struct node {int l,r,lmx,rmx,lmn,rmn,sum,mx,mn; }t[MAXN << 2]; int n, p[MAXN], m; void build(int i, int l, int r) {t[i].l = l;t[i].r = r;t[i].lmx = t[i].rmx = t[i].mx = -INF;t[i].lmn = t[i].rmn = t[i].mn = INF;if(l == r) {p[l] = i; return;}build(i<<1, l, M(i));build(i<<1|1, M(i)+1, r); } int max(int a,int b,int c) {return max(a,max(b,c)); } int min(int a,int b,int c) {return min(a,min(b,c)); } void upd(int pos, int v) {int i = p[pos];t[i].lmx = t[i].rmx = t[i].sum = t[i].lmn = t[i].rmn = t[i].mx = t[i].mn = v;i >>= 1;while(i){t[i].lmx = max(t[i<<1].lmx, t[i<<1].sum + t[i<<1|1].lmx);t[i].lmn = min(t[i<<1].lmn, t[i<<1].sum + t[i<<1|1].lmn);t[i].rmx = max(t[i<<1|1].rmx, t[i<<1|1].sum + t[i<<1].rmx);t[i].rmn = min(t[i<<1|1].rmn, t[i<<1|1].sum + t[i<<1].rmn);t[i].sum = t[i<<1].sum + t[i<<1|1].sum;t[i].mx = max(t[i<<1].mx,t[i<<1].rmx+t[i<<1|1].lmx,t[i<<1|1].mx);t[i].mn = min(t[i<<1].mn,t[i<<1].rmn+t[i<<1|1].lmn,t[i<<1|1].mn);i >>= 1;} } int main() {int t1, t2;scanf("%d", &n);build(1, 1, n);for(int i = 1; i <= n; i++){scanf("%d", &t1);upd(i, t1);}scanf("%d", &m);for(int i = 1; i <= m; i++){scanf("%d%d", &t1, &t2);upd(t1, t2);if(t[1].mx == t[1].sum && t[1].sum > 0)printf("%d\n",t[1].sum - t[1].mn);elseprintf("%d\n",max(t[1].mx,t[1].sum - t[1].mn));}return 0; }轉載于:https://www.cnblogs.com/geng4512/p/5296950.html
總結
以上是生活随笔為你收集整理的poj2750 PottedFlower(线段树的环状操作)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpriteBuilder中的粒子系统属
- 下一篇: 局域网内连接MySQL