POJ 3468 A Simple Problem with Integers(线段树)
题目链接:A Simple Problem with Integers
题意:N个数字,M次操作;操作分为两种,第一种将$[L,R]$区间内的每个数都加上C,第二种为求$[L,R]$区间内的数字和。
题解:线段树基本操作,区间修改和区间求和
1 #include <cstdio> 2 #define LC(a) ((a<<1)) 3 #define RC(a) ((a<<1)+1) 4 #define MID(a,b) ((a+b)>>1) 5 using namespace std; 6 7 typedef long long ll; 8 const int N=5e5*4; 9 ll ans=0; 10 11 struct node{ 12 ll l,r; 13 ll sum,add; 14 }tree[N]; 15 16 void pushup(ll p){ 17 tree[p].sum=tree[LC(p)].sum+tree[RC(p)].sum; 18 } 19 20 void pushdown(ll p){ 21 tree[LC(p)].add+=tree[p].add; 22 tree[RC(p)].add+=tree[p].add; 23 tree[LC(p)].sum+=tree[p].add*(tree[LC(p)].r-tree[LC(p)].l+1); 24 tree[RC(p)].sum+=tree[p].add*(tree[RC(p)].r-tree[RC(p)].l+1); 25 tree[p].add=0; 26 } 27 28 void build(ll p,ll l,ll r){ 29 tree[p].l=l; 30 tree[p].r=r; 31 tree[p].sum=tree[p].add=0; 32 if(l==r){ 33 scanf("%lld",&tree[p].sum); 34 return; 35 } 36 build(LC(p),l,MID(l,r)); 37 build(RC(p),MID(l,r)+1,r); 38 pushup(p); 39 } 40 41 void updata(ll p,ll l,ll r,ll num){ 42 if(r<tree[p].l||l>tree[p].r) return; 43 if(l<=tree[p].l&&r>=tree[p].r){ 44 tree[p].add+=num; 45 tree[p].sum+=num*(tree[p].r-tree[p].l+1); 46 return; 47 } 48 if(tree[p].add) pushdown(p); 49 updata(LC(p),l,r,num); 50 updata(RC(p),l,r,num); 51 pushup(p); 52 } 53 54 void query(ll p,ll l, ll r){ 55 if(r<tree[p].l||l>tree[p].r) return; 56 if(l<=tree[p].l&&r>=tree[p].r){ 57 ans+=tree[p].sum; 58 return; 59 } 60 if(tree[p].add) pushdown(p); 61 query(LC(p),l,r); 62 query(RC(p),l,r); 63 } 64 65 int main(){ 66 ll n,q; 67 char op[5]; 68 scanf("%lld%lld",&n,&q); 69 build(1,1,n); 70 while(q--){ 71 scanf("%s",op); 72 if(op[0]=='C'){ 73 ll l,r,add; 74 scanf("%lld%lld%lld",&l,&r,&add); 75 updata(1,l,r,add); 76 } 77 else{ 78 ans=0; 79 ll l,r; 80 scanf("%lld%lld",&l,&r); 81 query(1,l,r); 82 printf("%lld\n",ans); 83 } 84 } 85 return 0; 86 }