POJ3468(线段树区间求和+区间查询)
https://vjudge.net/contest/66989#problem/C
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
1 //线段树区间和裸题 2 //#include<bits/stdc++.h> 3 #include<iostream> 4 #include<stdio.h> 5 #include<string.h> 6 #define lson l,m,rt<<1 7 #define rson m+1,r,rt<<1|1 8 using namespace std; 9 const int maxn=100005; 10 long long sum[maxn<<2],add[maxn<<2]; 11 void pushup(int rt) 12 { 13 sum[rt]=sum[rt<<1]+sum[rt<<1|1]; 14 } 15 void pushdown(int rt,int ln,int rn) 16 { 17 if(add[rt]) 18 { 19 sum[rt<<1]+=add[rt]*ln; 20 sum[rt<<1|1]+=add[rt]*rn; 21 add[rt<<1]+=add[rt]; 22 add[rt<<1|1]+=add[rt]; 23 add[rt]=0; 24 } 25 } 26 void build(int l,int r,int rt) 27 { 28 if(r==l) 29 { 30 scanf("%lld",&sum[rt]); 31 return; 32 } 33 int m=(l+r)>>1; 34 build(lson); 35 build(rson); 36 pushup(rt); 37 } 38 void update(int L,int R,int c,int l,int r,int rt) 39 { 40 if(L<=l&&R>=r) 41 { 42 sum[rt]+=(long long)c*(r-l+1); 43 add[rt]+=c; 44 return; 45 } 46 int m=(l+r)>>1; 47 pushdown(rt,m-l+1,r-m); 48 if(L<=m) 49 update(L,R,c,lson); 50 if(R>m) 51 update(L,R,c,rson); 52 pushup(rt); 53 } 54 long long query(int L,int R,int l,int r,int rt) 55 { 56 if(L<=l&&R>=r) 57 { 58 return sum[rt]; 59 } 60 int m=(r+l)>>1; 61 pushdown(rt,m-l+1,r-m); 62 long long ans=0; 63 if(L<=m) 64 ans+=query(L,R,lson); 65 if(R>m) 66 ans+=query(L,R,rson); 67 return ans; 68 } 69 int main() 70 { 71 ios::sync_with_stdio(false); 72 cin.tie(0); 73 int n,m,x,y,z,q; 74 char h; 75 while(~scanf("%d%d",&n,&q)) 76 { 77 memset(sum,0,sizeof sum); 78 memset(add,0,sizeof add); 79 build(1,n,1); 80 for(int i=1;i<=q;i++) 81 { 82 getchar(); 83 scanf("%c",&h); 84 if(h=='Q') 85 { 86 scanf("%d%d",&x,&y); 87 cout<<query(x,y,1,n,1)<<endl; 88 } 89 else if(h=='C') 90 { 91 scanf("%d%d%d",&x,&y,&z); 92 update(x,y,z,1,n,1); 93 } 94 } 95 } 96 return 0; 97 }
注意点:
是道裸题了
BUT 在输入数据的时候 ,scanf("%lld",&sum[rt]);一开始把它写成%d了,害我WA了好几发;
sum[rt]+=(long long)c*(r-l+1); 一开始没注意把数据转化为long long(>人<;)。
以后一定要注意呀!