和普通的线段树不同的是,查询x~y的话,给出的答案是第一个值的一倍加上第二个值的两倍一直到第n个值的n倍。
思路的话,就是关于query和pushup的方法。用一个新的变量sum记录一下这个区间里面按照答案给出的方式的值,比如说,这个节点的区间是1~3,那么这个节点的sum值就是(1*val[1]+2*val[2]+3*val[3])。那么对于pushup操作,当前这个节点的sum值是左边的sum值+左边的区间长度*右边的c值(c值代表的是这个区间的所有元素的和)+右边的sum值。这样的话就相当于右边的sum升高了需要的高度,就满足题意了。
另外关于query也是类似,要返回时,加上(l-ql)倍的c[o]的值就行了,这样就相当于右边的sum升高了(l-ql)的高度了。如果不能理解,可以手动模拟一下试试。
但是这题WA了好多次,,因为我现在才知道原来uva的long long得用lld,QAQ。。。
具体见代码:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #define t_mid (l+r>>1) 5 #define ls o<<1 6 #define rs o<<1 | 1 7 #define lson ls,l,t_mid 8 #define rson rs,t_mid+1,r 9 using namespace std; 10 typedef long long ll; 11 12 const int N = 100000 + 5; 13 ll c[N<<2],sum[N<<2],add[N<<2]; 14 15 void pushup(int o,int len){c[o]=c[ls]+c[rs];sum[o]=sum[ls]+c[rs]*len+sum[rs];} 16 17 void build(int o,int l,int r) 18 { 19 add[o]=0; 20 if(l==r) {c[o]=sum[o]=100;return;} 21 build(lson); 22 build(rson); 23 pushup(o,t_mid-l+1); 24 } 25 26 void pushdown(int o,int len) 27 { 28 if(add[o]) 29 { 30 int llen=(len-(len>>1)),rlen=(len>>1); 31 add[ls] += add[o]; 32 add[rs] += add[o]; 33 c[ls] += add[o]*llen; 34 c[rs] += add[o]*rlen; 35 sum[ls] += add[o]*(llen)*(llen+1)/2; 36 sum[rs] += add[o]*(rlen)*(rlen+1)/2; 37 add[o]=0; 38 } 39 } 40 41 void update(int o,int l,int r,int ql,int qr,int dt) 42 { 43 if(ql <= l && qr >= r) 44 { 45 add[o] += (ll)dt; 46 c[o] += (ll)dt*(r-l+1); 47 sum[o] += (ll)dt*(r-l+1)*(r-l+2)/2; 48 return; 49 } 50 pushdown(o,r-l+1); 51 if(ql <= t_mid) update(lson,ql,qr,dt); 52 if(qr >t_mid) update(rson,ql,qr,dt); 53 pushup(o,t_mid-l+1); 54 } 55 56 ll query(int o,int l,int r,int ql,int qr) 57 { 58 if(ql <= l && qr >= r) 59 { 60 return (l-ql)*c[o]+sum[o]; 61 } 62 pushdown(o,r-l+1); 63 ll res = 0; 64 if(ql <= t_mid) res += query(lson,ql,qr); 65 if(qr > t_mid) res += query(rson,ql,qr); 66 return res; 67 } 68 69 int main() 70 { 71 int T; 72 scanf("%d",&T); 73 for(int kase=1;kase<=T;kase++) 74 { 75 printf("Case %d: ",kase); 76 int n,m; 77 scanf("%d%d",&n,&m); 78 build(1,1,n); 79 80 while(m--) 81 { 82 char s[10]; 83 scanf("%s",s); 84 if(s[0]=='c') 85 { 86 int x,y,dt; 87 scanf("%d%d%d",&x,&y,&dt); 88 update(1,1,n,x,y,dt); 89 } 90 else 91 { 92 int x,y; 93 scanf("%d%d",&x,&y); 94 printf("%lld ",query(1,1,n,x,y)); 95 } 96 } 97 } 98 }