Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 43776 | Accepted: 12806 | |
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
//线段树的延迟更新,不然每次都操作到具体叶节点会耗费大量的时间!此题用add标记每个节点有无操作,不必每次都搜索至叶节点,从而节省大量的时间!
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; #define MAX 100003 typedef __int64 ll; ll da[MAX],ans; struct node { ll left,right,add; ll sum; }tree[MAX*4]; //建立以left,right为左右边界,将数组a中元素存储在首地址从1开始的tree数组中 void build( ll id, ll left, ll right ) { tree[id].add=0; tree[id].left = left; tree[id].right = right; if( left == right ) { tree[id].sum = da[left]; return ; } else { ll mid = ( left + right )>>1; build( id <<1, left, mid ); build( id<<1|1, mid + 1, right ); tree[id].sum = tree[id<<1].sum + tree[id<<1|1].sum; } } //修改 void updata( ll id, ll left, ll right, ll adi) { if(tree[id].left==left&&tree[id].right==right) { tree[id].add+=adi; return ; } else { if(tree[id].add!=0) { tree[id].sum+=(tree[id].right-tree[id].left+1)*tree[id].add; tree[id<<1].add+=tree[id].add; tree[id<<1|1].add+=tree[id].add; tree[id].add=0; } tree[id].sum+=( right-left+1)*adi; ll mid=(tree[id].left+tree[id].right)>>1; if(right<=mid) updata(id<<1,left,right,adi); else if(left>mid) updata(id<<1|1,left,right,adi); else { updata(id<<1,left,mid,adi); updata(id<<1|1,mid+1,right,adi); } } } //3.查询 //***************************************************************** void query(ll id, ll left, ll right) { if( tree[id].left==left&&tree[id].right== right) { if(tree[id].add==0) { ans+=tree[id].sum; return ; } else { ans+=tree[id].sum+(tree[id].right-tree[id].left+1)*tree[id].add; return ; } } else { if(tree[id].add!=0) { tree[id].sum+=(tree[id].right-tree[id].left+1)*tree[id].add; tree[id<<1].add+=tree[id].add; tree[(id<<1)+1].add+=tree[id].add; tree[id].add=0; } ll mid = (tree[id].left+tree[id].right)>>1; if(right<= mid ) query( id <<1, left,right); else if(left>mid ) query( (id <<1)+ 1,left, right); else { query( id <<1, left,mid); query( (id<<1) + 1, mid+1,right ); } } } int main() { ll n,i,m; scanf("%I64d%I64d",&n,&m); //while(~scanf("%d%d",&n,&m)) // { for(i=1;i<=n;i++) scanf("%I64d",&da[i]); build(1,1,n); for(i=0;i<m;i++) { ll a,b,c; char op; scanf(" %c",&op); if(op=='C') { scanf("%I64d%I64d%I64d",&a,&b,&c); updata(1,a,b,c); } else if(op=='Q') { ans=0; scanf("%I64d%I64d",&a,&b); query(1, a,b); printf("%I64d\n",ans); } } //} return 0; }