POJ 3468.A Simple Problem with Integers-线段树(成段增减、区间查询求和)
POJ 3468.A Simple Problem with Integers
这个题就是成段的增减以及区间查询求和操作。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<cstdlib> 6 #include<algorithm> 7 #include<queue> 8 #include<map> 9 using namespace std; 10 typedef long long ll; 11 const int maxn=1e5+10; 12 const int inf=0x3f3f3f3f; 13 #define lson l,m,rt<<1 14 #define rson m+1,r,rt<<1|1 15 ll tree[maxn<<2],add[maxn<<2]; 16 17 void pushup(int rt) 18 { 19 tree[rt]=tree[rt<<1]+tree[rt<<1|1]; 20 } 21 void pushdown(int rt,int m) 22 { 23 if(add[rt]){ 24 add[rt<<1]+=add[rt]; 25 add[rt<<1|1]+=add[rt]; 26 tree[rt<<1]+=(m-(m>>1))*add[rt]; 27 tree[rt<<1|1]+=(m>>1)*add[rt]; 28 add[rt]=0; 29 } 30 } 31 void build(int l,int r,int rt) 32 { 33 add[rt]=0; 34 if(l==r){ 35 scanf("%lld",&tree[rt]); 36 return ; 37 } 38 39 int m=(l+r)>>1; 40 build(lson); 41 build(rson); 42 pushup(rt); 43 } 44 void update(int L,int R,ll c,int l,int r,int rt) 45 { 46 if(L<=l&&r<=R){ 47 add[rt]+=c; 48 tree[rt]+=c*(r-l+1); 49 return ; 50 } 51 52 pushdown(rt,r-l+1); 53 int m=(l+r)>>1; 54 if(L<=m) update(L,R,c,lson); 55 if(R> m) update(L,R,c,rson); 56 pushup(rt); 57 } 58 ll query(int L,int R,int l,int r,int rt) 59 { 60 if(L<=l&&r<=R){ 61 return tree[rt]; 62 } 63 64 pushdown(rt,r-l+1); 65 int m=(l+r)>>1; 66 ll ret=0; 67 if(L<=m)ret+=query(L,R,lson); 68 if(R> m)ret+=query(L,R,rson); 69 return ret; 70 } 71 int main() 72 { 73 int n,m; 74 scanf("%d%d",&n,&m); 75 build(1,n,1); 76 char s[5];int l,r;ll c; 77 for(int i=0;i<m;i++){ 78 scanf("%s",s); 79 if(s[0]=='Q'){ 80 scanf("%d%d",&l,&r); 81 printf("%lld\n",query(l,r,1,n,1)); 82 } 83 else{ 84 scanf("%d%d%lld",&l,&r,&c); 85 update(l,r,c,1,n,1); 86 } 87 } 88 return 0; 89 }