题目地址:POJ 3468
打了个篮球回来果然神经有点冲动。
。
无脑的狂交了8次WA。。竟然是更新的时候把r-l写成了l-r。。。
这题就是区间更新裸题。
区间更新就是加一个lazy标记,延迟标记,仅仅有向下查询的时候才将lazy标记向下更新。其它的均按线段树的来即可。
代码例如以下:
#include <iostream> #include <cstdio> #include <cstring> #include <math.h> #include <stack> using namespace std; #define LL long long #define lson l, mid, rt<<1 #define rson mid+1, r, rt<<1|1 const int MAXN=1e5+10; LL sum[MAXN<<2]; LL lazy[MAXN<<2]; void PushUp(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void PushDown(int rt, int m) { if(lazy[rt]) { lazy[rt<<1]+=lazy[rt]; lazy[rt<<1|1]+=lazy[rt]; sum[rt<<1]+=lazy[rt]*(m-(m>>1)); sum[rt<<1|1]+=lazy[rt]*(m>>1); lazy[rt]=0; } } void build(int l, int r, int rt) { lazy[rt]=0; if(l==r) { scanf("%lld",&sum[rt]); return ; } int mid=(l+r)>>1; build(lson); build(rson); PushUp(rt); } void update(int ll, int rr, int x, int l, int r, int rt) { if(ll<=l&&rr>=r) { lazy[rt]+=x; sum[rt]+=(LL)x*(r-l+1); return ; } PushDown(rt, r-l+1); int mid=(l+r)>>1; if(ll<=mid) update(ll,rr,x,lson); if(rr>mid) update(ll,rr,x,rson); PushUp(rt); } LL query(int ll, int rr, int l, int r, int rt) { if(ll<=l&&rr>=r) { return sum[rt]; } PushDown(rt,r-l+1); LL ans=0; int mid=(l+r)>>1; if(ll<=mid) ans+=query(ll,rr,lson); if(rr>mid) ans+=query(ll,rr,rson); return ans; } int main() { int n, q, i, a, b, c; char ch[3]; scanf("%d%d",&n,&q); build(1,n,1); while(q--) { getchar(); scanf("%s",&ch); if(ch[0]=='Q') { scanf("%d%d",&a,&b); LL ans=query(a,b,1,n,1); printf("%lld ",ans); } else { scanf("%d%d%d",&a,&b,&c); update(a,b,c,1,n,1); } } return 0; }