|
沙发
楼主 |
发表于 2019-11-7 22:36:54
|
只看该作者
- ///先决条件 位操作 树状数组(?)
- #include<bits/stdc++.h>
- using namespace std;
- const int mn=100;
- int A[mn]; //原数组
- int Sum[mn<<2];//Sum求和,开四倍空间
- int Tag[mn<<2];//lazy标记
- int n,k,x,y,z;
- ///左儿子
- int ls(int p){return (p<<1);}
- ///右儿子
- int rs(int p){return (p<<1|1);}
- //PushUp函数更新节点信息,这里是求和
- void PushUp(int p){ Sum[p]=Sum[ls(p)]+Sum[rs(p)];}
- void f(int l,int r,int p,int k) ///lr区间的数加上k
- {
- Tag[p]+=k;
- Sum[p]+=k*(r-l+1);
- }
- void PushDown(int l,int r,int p)
- {
- int m=(l+r)>>1;
- f(l,m,ls(p),Tag[p]);
- f(m+1,r,rs(p),Tag[p]);
- Tag[p]=0;
- }
- void Update(int L,int R,int k,int l,int r,int p)
- {
- if(L<=l && r<=R)
- {
- Sum[p]+=k*(r-l+1);
- Tag[p]+=k;
- return;
- }
- PushDown(l,r,p);
- int m=(l+r)>>1;
- if(L<=m) Update(L,R,k,l,m,ls(p));
- if(R>m) Update(L,R,k,m+1,r,rs(p));
- }
- //Build函数建立线段树
- void Build(int l,int r,int p) //[l,r]表示当前节点区间,p表示当前节点的实际存储位置
- {
- if(l==r) //若到达叶节点
- {
- Sum[p]=A[l];//存储A数组的值
- return;
- }
- int m=(l+r)>>1;
- Build(l,m,ls(p));
- Build(m+1,r,rs(p));
- //更新信息
- PushUp(p);
- }
- int Query(int L,int R,int l,int r,int p)
- ///[L,R]表示操作区间,[l,r]表示当前区间,p当前节点编号
- {
- if(L<=l && r<=R) return Sum[p];
- int m=(l+r)>>1;
- int ANS=0;
- if(L<=m) ANS+=Query(L,R,l,m,ls(p));
- if(R>m) ANS+=Query(L,R,m+1,r,rs(p));
- return ANS;
- }
- int main()
- {
- n=20;
- for (int i=1; i<=20; i++) A[i]=9+i; ///假设20个数字是10-29
- Build(1,n,1);
- cin>>k; ///进行k次区间修改
- while (k--)
- {
- cin>>x>>y>>z; ///xy区间加上z
- Update(x,y,z,1,n,1); ///
- cout<<Query(x,y,1,n,1);///输出区间和
- }
- return 0;
- }
复制代码 |
|