Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 60462 | Accepted: 18430 | |
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/* 更新 Time:2015-1-18 20:33 */ #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 typedef long long LL; const int MAX=100000+10; struct Tree{ LL nSum,ad; }tree[MAX<<2]; void Build(int l,int r,int rt){ tree[rt].nSum=0;tree[rt].ad=0; if(l==r)return; int mid=(l+r)>>1; Build(lson); Build(rson); } void Insert(int pos,LL val,int l,int r,int rt){ if(l==r){ tree[rt].nSum=val; return; } tree[rt].nSum+=val; int mid=(l+r)>>1; if(pos<=mid) Insert(pos,val,lson); else if(pos>mid) Insert(pos,val,rson); } void Add(int L,int R,LL val,int l,int r,int rt){ if(L==l&&R==r){ tree[rt].ad+=val; return; } tree[rt].nSum+=(R-L+1)*val; int mid=(l+r)>>1; if(R<=mid){ Add(L,R,val,lson); }else if(L>mid){ Add(L,R,val,rson); }else{ Add(L,mid,val,lson); Add(mid+1,R,val,rson); } } LL Query(int L,int R,int l,int r,int rt){ if(L==l&&R==r){ return tree[rt].ad*(r-l+1)+tree[rt].nSum; } tree[rt].nSum+=tree[rt].ad*(r-l+1); int mid=(l+r)>>1; Add(l,mid,tree[rt].ad,lson); Add(mid+1,r,tree[rt].ad,rson); tree[rt].ad=0; if(R<=mid){ return Query(L,R,lson); }else if(L>mid){ return Query(L,R,rson); }else{ return Query(L,mid,lson)+ Query(mid+1,R,rson); } } int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF){ int pos; LL val; memset(tree,0,sizeof(tree)); Build(1,n,1); for(int i=1;i<=n;i++){ scanf("%lld",&val); Insert(i,val,1,n,1); } /* for(int i=1;i<=n*2+1;i++){ printf(" %d",tree[i].ad); }puts(""); */ char cmd[10]; int L,R; while(m--){ scanf("%s",cmd); if(cmd[0]=='Q'){ scanf("%d%d",&L,&R); printf("%lld\n",Query(L,R,1,n,1)); }else{ scanf("%d%d%lld",&L,&R,&val); Add(L,R,val,1,n,1); } } } return 0; }
<span style="font-family: Arial, Helvetica, sans-serif;">/*</span>
题目大意:给n个数字,查询求区间和以及区间修改 关键:线段树的应用 数据用 long long 型 Time:2014-8-4 13:16 */ #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAX=100000+10; struct CNode { int L,R; long long nSum,lnc; int Mid() {return (L+R)/2;} }Tree[4*MAX]; void BuildTree(int Root,int L,int R) { Tree[Root].L=L; Tree[Root].R=R; Tree[Root].nSum=0; Tree[Root].lnc=0; if(L==R)return ; BuildTree(Root*2+1,L,Tree[Root].Mid()); BuildTree(Root*2+2,Tree[Root].Mid()+1,R); } void Insert(int Root,int pos,long long v) { if(Tree[Root].L==pos&&Tree[Root].R==pos)//也可以L==R { Tree[Root].nSum=v;//Root.lnc=v; return; } Tree[Root].nSum+=v; if(pos<=Tree[Root].Mid()) Insert(Root*2+1,pos,v); else Insert(Root*2+2,pos,v); } void Add(int Root,int a,int b,long long c) { if (Tree[Root].L==a&&Tree[Root].R==b) { Tree[Root].lnc+=c; return; } Tree[Root].nSum+=(b-a+1)*c;//此处应该为 c 不是 lnc 此处出错 if(b<=Tree[Root].Mid()) Add(Root*2+1,a,b,c); else if(a>=Tree[Root].Mid()+1) { Add(Root*2+2,a,b,c); } else { Add(Root*2+1,a,Tree[Root].Mid(),c); Add(Root*2+2,Tree[Root].Mid()+1,b,c); } } long long QuerynSum(int Root,int s,int e) { if(Tree[Root].L==s&&Tree[Root].R==e) { return Tree[Root].nSum+(Tree[Root].R-Tree[Root].L+1)*Tree[Root].lnc; } Tree[Root].nSum+=(Tree[Root].R-Tree[Root].L+1)*Tree[Root].lnc; Add(Root*2+1,Tree[Root].L,Tree[Root].Mid(),Tree[Root].lnc); Add(Root*2+2,Tree[Root].Mid()+1,Tree[Root].R,Tree[Root].lnc); Tree[Root].lnc=0; if(e<=Tree[Root].Mid()) return QuerynSum(Root*2+1,s,e); else if(s>=Tree[Root].Mid()+1) return QuerynSum(Root*2+2,s,e); else { return QuerynSum(Root*2+1,s,Tree[Root].Mid())+ QuerynSum(Root*2+2,Tree[Root].Mid()+1,e); } } int main() { int N,q; while(scanf("%d%d",&N,&q)!=EOF) { memset(Tree,0,sizeof(Tree)); BuildTree(0,1,N); for(int i=1;i<=N;i++) { long long v; scanf("%lld",&v); Insert(0,i,v); } /* for(int i=0;i<=4*N;i++) printf("%d %d\n",Tree[i].L,Tree[i].R); */ char cmd[10]; while(q--) { scanf("%s",cmd); if(cmd[0]=='Q') { int s,e; scanf("%d%d",&s,&e); printf("%lld\n",QuerynSum(0,s,e)); //long long 型 } else { int a,b; long long c; scanf("%d%d%lld",&a,&b,&c); Add(0,a,b,c); } } } return 0; }