分析:这题wa了好多次(看了下discuss好多人也是这样,好题~)。一处是sum值会超int32,要用int64。还有一处是toadd要累加,我不知道是受上一题影响还是怎的..pushdown的时候直接替换了...还有,据说北大oj要用%lld读..
类型:成段更新。容易错. 线段树(貌似这题也能用树状数组做?......)
代码:
//3wa #include<cstdio> #include<cstring> #include<iostream> using namespace std; #define MAXN 100002 #define int64 long long #define lc e<<1 #define rc e<<1|1 struct node{ int l, r, mid, toadd; int64 v; }a[MAXN*4]; int n; void pushup(int e) { a[e].v=a[lc].v+a[rc].v; } void pushdown(int e) { int t = a[e].toadd; if(t) //这里是对的 { a[e].toadd=0; a[lc].v+=(int64)(a[lc].r-a[lc].l+1)*t; a[rc].v+=(int64)(a[rc].r-a[rc].l+1)*t; // a[lc].toadd=a[rc].toadd=t; //增量是累加的。写上一题 hdu1698 Just a Hook 写傻掉了. a[lc].toadd+=t; a[rc].toadd+=t; } } void build(int l, int r, int e) { a[e].l=l; a[e].r=r; if(l==r) scanf("%lld", &a[e].v); //这里没用%lld 又wa了一次.... else { a[e].mid=l+((r-l)>>1); //???? build(l, a[e].mid, lc); build(a[e].mid+1, r, rc); pushup(e); } } void update(int L, int R, int add, int l, int r, int e) { if(L<=l && r<=R) { a[e].v+=(int64)(a[e].r-a[e].l+1)*add; // a[e].toadd=add; //这里也一样!! a[e].toadd+=add; } else { pushdown(e); if(L<=a[e].mid) update(L, R, add, l, a[e].mid, lc); if(a[e].mid < R) update(L, R, add, a[e].mid+1, r, rc); pushup(e); } } int64 query(int L, int R, int l, int r, int e) { int64 ret=0; if(L<=l && r<=R) { ret+=a[e].v; } else { pushdown(e); //查询也要推下去 if(L<=a[e].mid) ret+=query(L, R, l, a[e].mid, lc); if(a[e].mid<R) ret+=query(L, R, a[e].mid+1, r, rc); pushup(e); //不用。 } return ret; } int main() { int q; scanf("%d%d", &n, &q); build(1, n, 1); char t[2]; while(q--) { int x, y; scanf("%s%d%d", t, &x, &y); if(t[0]=='Q') { printf("%lld\n", query(x, y, 1, n, 1)); //poj 用 %lld } else { int add; scanf("%d", &add); update(x, y, add, 1, n, 1); } } }