uva 12501 - Bulky process of bulk reduction 线段树 不好想

来源:互联网 发布:电脑软件网推荐 编辑:程序博客网 时间:2024/06/08 09:19
//uva 12501 - Bulky process of bulk reduction/*题目地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3945题意:一个数列a[],初始化所有元素为100,有两种操作:1、更新操作:将一段连续的区间[i,j]都加上一个值v: a[i]+v;a[i+1]+v;...a[j]+v;2、查询操作:查询a[i]*1 + a[i+1]*2 + a[i+2]*3 + ... + a[j]*(j+1)的值思路:线段树维护两个值s,sum:s为区间[l,r]的a[l]+a[l+1]+a[l+2]+...a[r]的和sum为区间[l,r]的a[l]*1+a[l+1]*2+a[l+2]*3+...+a[r]*(r+1)的和这样如果包含有某个区间那就这样区间的值就是sum+s*num,s为该区间[l,r]的右孩子,num为该区间左孩子中在[l,r]中的个数。比如查询区间[2,4],a[2] = 100;a[3]=100; a[4]=100;线段树中:sum[2,2] = a[2,2];  sum[3,4] = a[3,3]*1 + a[4,4]*2;-->sum[2,4] = a[2,2]*1 + a[3,3]*1 + a[4,4]*2线段树中区间[2,4]的右孩子[3,4]的s[3,4] = a[3,3] + a[4,4],左孩子[1,2]在[2,4]的个数为1所以 ans=  a[2,2]*1 + a[3,3]*1 + a[4,4]*2 +(a[3,3] + a[4,4])*1=  a[2,2]*1 + a[3,3]*2 + a[4,4]*3说的有点乱,画一画再参考下代码就会明白。*/#include<stdio.h>#include<string.h>#include<stdlib.h>#define N 100005#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,r#define int64 long longint64 s[N<<2],sum[N<<2],add[N<<2];void Pushup(int rt,int m){s[rt] = s[rt<<1] + s[rt<<1|1];sum[rt] = sum[rt<<1] + s[rt<<1|1] *(m-(m>>1)) + sum[rt<<1|1];}void Pushdown(int rt,int m){if(add[rt]){int64 a = m-(m>>1);int64 b = (m>>1);add[rt<<1] += add[rt];add[rt<<1|1] += add[rt];s[rt<<1] += add[rt] * a;s[rt<<1|1] += add[rt] * b;sum[rt<<1] += (1+a)*a/2*add[rt];sum[rt<<1|1] += (1+b)*b/2*add[rt];add[rt] = 0;}}void Build(int rt,int l,int r){add[rt] = 0;if(l == r){s[rt] = sum[rt] = 100;return;}int mid = (l + r) >> 1;Build(lson);Build(rson);Pushup(rt,r-l+1);}void Update(int rt,int l,int r,int L,int R,int val){int64 v = (int64)val;if(L <= l && R >= r){add[rt] += v;s[rt] += v * (r-l+1);sum[rt] += v * (r-l+2) * (r-l+1) / 2;return;}Pushdown(rt,r-l+1);int mid = (l + r) >> 1;if(L <= mid) Update(lson,L,R,val);if(R > mid ) Update(rson,L,R,val);Pushup(rt,r-l+1);}int64 Query(int rt,int l,int r,int L,int R){if(L <= l && R >= r){return s[rt]*(l-L)+sum[rt];}Pushdown(rt,r-l+1);int mid = (l + r) >> 1;int64 res = 0;if(L <= mid) res += Query(lson,L,R);if(R > mid ) res += Query(rson,L,R);return res;}int main(){int i,T,n,m,ca = 1;char op[10];int a,b,c;scanf("%d",&T);while(T--){scanf("%d %d",&n,&m);printf("Case %d:\n",ca++);Build(1,1,n);while(m--){scanf("%s",op);if(op[0] == 'q'){scanf("%d %d",&a,&b);printf("%lld\n",Query(1,1,n,a,b));}else{scanf("%d %d %d",&a,&b,&c);Update(1,1,n,a,b,c);}}}return 0;}

原创粉丝点击