A - A Simple Problem with Integers (线段树的区间修改与区间查询)
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
10 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4
Sample Output
4 55 9 15 代码如下 #include #include typedef long long ll; const int N=1e5+7; int n,q; int a[N]; struct node{ //建树 int l,r,len;//多了一个区间长度len和懒标记 ll sum,lazy; }tree[N*4]; void pushup(int now){//向上更新sum tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum; } void buildtree(int now, int l,int r){ tree[now].l=l; tree[now].r=r; tree[now].lazy=0;// 建树时懒标记置零 tree[now].len=r-l+1; if(l==r){ tree[now].sum=a[l]; return; } int mid=(l+r)>>1; buildtree(now<<1,l,mid); buildtree(now<<1|1,mid+1,r); pushup(now); } void pushdown(int now){ //向子孙传递懒标记 if(tree[now].lazy){ tree[now<<1].sum+=tree[now].lazy*tree[now<<1].len; tree[now<<1].lazy+=tree[now].lazy; tree[now<<1|1].sum+=tree[now].lazy*tree[now<<1|1].len; tree[now<<1|1].lazy+=tree[now].lazy; tree[now].lazy=0; } } void add(int now,int l,int r,int v){ int L=tree[now].l,R=tree[now].r; if(l<=L&&R<=r){//如果现区间已经完全在所要修改的区间以内,则不需要继续向下修改,进行懒标记就好 tree[now].sum+=tree[now].len*v; tree[now].lazy+=v; return; } pushdown(now);//懒标记由父辈传给子辈 int mid=(L+R)>>1; if(mid>=l)add(now<<1,l,r,v);//与左儿子有交集 if(mid<r)add(now<<1|1,l,r,v);//与右儿子有交集 pushup(now); } ll query(int now,int l,int r){ int L=tree[now].l,R=tree[now].r; if(l==L&&r==R)return tree[now].sum;//现区间的边界与需要查询的边界刚刚好相同直接返回 pushdown(now);//真正懒的所在,需要用到的时候懒标记才会继续向下传递,add里面并没有将子孙更新完全 int mid=(L+R)>>1; if(l>mid)return query(now<<1|1,l,r); else if(r<=mid)return query(now<<1,l,r); else return query(now<<1,l,mid)+query(now<<1|1,mid+1,r); } int main(){ scanf("%d%d",&n,&q); for(int i=1;i<=n;i++)scanf("%d",&a[i]); buildtree(1,1,n); while(q--){ char str[3]; scanf("%s",str); if(str[0]=='C'){ int x,y,v; scanf("%d%d%d",&x,&y,&v); add(1,x,y,v); } else{ int x,y; scanf("%d%d",&x,&y); printf("%lld\n",query(1,x,y)); } } return 0; }