1. 程式人生 > >POJ 3468 A Simple Problem with Integers(線段樹)

POJ 3468 A Simple Problem with Integers(線段樹)

truct fin clas define class 基本 open urn display

題目鏈接: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 }
Code

POJ 3468 A Simple Problem with Integers(線段樹)