A Simple Problem with Integers
Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 92127 | Accepted: 28671 | |
Case Time Limit: 2000MS |
描述
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.
输入
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.
输出
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
Hint
The sums may exceed the range of 32-bit integers.
Source
POJ Monthly--2007.11.25, Yang Yi、
前几次提交的时候没有吧node[u].add清零,一直WA
第一道线段树的题,当晚没有调出来,第二天才想出来,不错
#include<cstdio> #include<iostream> #define LL long long #define R(u) (u<<1|1) #define L(u) (u<<1) using namespace std; const int maxx=100005; LL a[maxx]; int n,m; struct Node{ int r,l; LL add,sum; }node[maxx<<2]; void Pushup(int u) { node[u].sum=node[L(u)].sum+node[R(u)].sum; return; } void Pushdown(int u) { node[L(u)].add+=node[u].add; node[R(u)].add+=node[u].add; node[L(u)].sum+=(node[L(u)].r-node[L(u)].l+1)*node[u].add; node[R(u)].sum+=(node[R(u)].r-node[R(u)].l+1)*node[u].add; node[u].add=0; //一定记得清零 } void Build(int u,int left,int right) { node[u].l=left,node[u].r=right; node[u].add=0; if(left==right) { node[u].sum=a[left]; return; } int mid=(left+right)>>1; Build(L(u),left,mid); Build(R(u),mid+1,right); Pushup(u); } void update(int u,int left,int right,LL val) { if(left==node[u].l&&node[u].r==right) { node[u].add+=val; node[u].sum+=(node[u].r-node[u].l+1)*val; return; } node[u].sum+=(right-left+1)*val;// 当更新区间小于这段 int mid=(node[u].r+node[u].l)>>1; if(mid>=right) update(L(u),left,right,val);//在左边 else if(mid<left) update(R(u),left,right,val); else { update(L(u),left,mid,val); update(R(u),mid+1,right,val); } //Pushup(u);前面已经直接算出sum后面不用再Pushup了 } LL Qurey(int u,int left,int right) { if(left==node[u].l&&node[u].r==right) return node[u].sum; if(node[u].add)Pushdown(u); int mid=(node[u].r+node[u].l)>>1; if(mid>=right) Qurey(L(u),left,right); else if(mid<left) Qurey(R(u),left,right); else return (Qurey(L(u),left,mid)+Qurey(R(u),mid+1,right)); //Pushup(u); } int main() { cin>>n>>m; LL c; for(int i=1;i<=n;i++) scanf("%I64d",a+i); Build(1,1,n); while(m--) {char x;int ai,an; scanf("%c %d %d",&x,&ai,&an); cin>>x>>ai>>an; if(x=='C') { scanf("%I64d",&c); update(1,ai,an,c); } else printf("%I64d ",Qurey(1,ai,an)); } return 0; }