Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 60899 | Accepted: 18576 | |
Case Time Limit: 2000MS |
Description
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
题意:区间更新,区间查询的线段树。
AC代码如下:
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
struct node
{ int l,r;
ll sum,add;
}tree[400010];
void down(int tr)
{ if(tree[tr].add!=0)
{ tree[tr*2].sum+=tree[tr].add*(tree[tr*2].r-tree[tr*2].l+1);
tree[tr*2+1].sum+=tree[tr].add*(tree[tr*2+1].r-tree[tr*2+1].l+1);
tree[tr*2].add+=tree[tr].add;
tree[tr*2+1].add+=tree[tr].add;
tree[tr].add=0;
}
}
void build(int tr,int l,int r)
{ tree[tr].l=l;
tree[tr].r=r;
if(l==r)
{ scanf("%I64d",&tree[tr].sum);
tree[tr].add=0;
return;
}
int mid=(l+r)/2;
build(tr*2,l,mid);
build(tr*2+1,mid+1,r);
tree[tr].sum=tree[tr*2].sum+tree[tr*2+1].sum;
tree[tr].add=0;
}
void update(int tr,int l,int r,ll add)
{ if(tree[tr].l==l && tree[tr].r==r)
{ tree[tr].sum+=(r-l+1)*add;
tree[tr].add+=add;
return;
}
down(tr);
int mid=(tree[tr].l+tree[tr].r)/2;
if(r<=mid)
update(tr*2,l,r,add);
else if(l>mid)
update(tr*2+1,l,r,add);
else
{ update(tr*2,l,mid,add);
update(tr*2+1,mid+1,r,add);
}
tree[tr].sum=tree[tr*2].sum+tree[tr*2+1].sum;
}
long long query(int tr,int l,int r)
{ if(tree[tr].l==l && tree[tr].r==r)
return tree[tr].sum;
down(tr);
int mid=(tree[tr*2].l+tree[tr*2+1].r)/2;
if(r<=mid)
return query(tr*2,l,r);
else if(l>=mid+1)
return query(tr*2+1,l,r);
else
return query(tr*2,l,mid)+query(tr*2+1,mid+1,r);
}
char s[10];
int main()
{ int n,m,i,j,k,l,r;
ll add;
scanf("%d%d",&n,&m);
build(1,1,n);
while(m--)
{ scanf("%s",s);
if(s[0]=='Q')
{ scanf("%d%d",&l,&r);
printf("%I64d\n",query(1,l,r));
}
else
{ scanf("%d%d%I64d",&l,&r,&add);
update(1,l,r,add);
}
}
}