POJ 3468-A Simple Problem with Integers:
线段树经典板子题,注意当数据范围大于是1e5的时候,采用线段树求解,才可以AC。
区间更新的时候注意不要忘记加上lazy标记,减少更新的次数!!!
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cmath> 5 #include<vector> 6 #include<string> 7 using namespace std; 8 //正统线段树板子题。。。 9 const int maxn=1e5+10; 10 typedef long long ll; 11 int a[maxn*2]; 12 13 struct node{ 14 int l,r; 15 ll sum,lazy; 16 void update(ll x){ 17 sum+=1ll*(r-l+1)*x; 18 lazy+=x; 19 } 20 }tree[maxn<<2]; 21 22 void push_up(int rt){ 23 tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum; 24 } 25 26 void push_down(int rt){ 27 ll lazyval=tree[rt].lazy; 28 if(lazyval){ 29 tree[rt<<1].update(lazyval); 30 tree[rt<<1|1].update(lazyval); 31 tree[rt].lazy=0; 32 } 33 } 34 35 void build(int rt,int l,int r){ 36 tree[rt].l=l,tree[rt].r=r; 37 tree[rt].sum=0,tree[rt].lazy=0; 38 if(l==r){ 39 tree[rt].sum=a[l]; 40 return ; 41 }else{ 42 int mid=(l+r)>>1; 43 build(rt<<1,l,mid); 44 build(rt<<1|1,mid+1,r); 45 push_up(rt); 46 } 47 } 48 49 void update(ll val,int l,int r,int rt){ 50 int L=tree[rt].l,R=tree[rt].r; 51 if(l<=L&&r>=R){ 52 tree[rt].update(val); 53 return ; 54 }else{ 55 push_down(rt); 56 int mid=(L+R)>>1; 57 if(l<=mid){ 58 update(val,l,r,rt<<1); 59 } 60 if(r>mid){ 61 update(val,l,r,rt<<1|1); 62 } 63 push_up(rt); 64 } 65 } 66 67 ll query(int l,int r,int rt){ 68 int L=tree[rt].l,R=tree[rt].r; 69 if(l<=L&&r>=R){ 70 return tree[rt].sum; 71 }else{ 72 push_down(rt); 73 int mid=(L+R)>>1; 74 ll ans=0; 75 if(l<=mid){ 76 ans+=query(l,r,rt<<1); 77 } 78 if(r>mid){ 79 ans+=query(l,r,rt<<1|1); 80 } 81 push_up(rt); 82 return ans; 83 } 84 } 85 int main(){ 86 int n,m; 87 scanf("%d%d",&n,&m); 88 for(int i=1;i<=n;i++){ 89 scanf("%d",&a[i]); 90 } 91 build(1,1,n); 92 for(int i=0;i<m;i++){ 93 int l;int r;ll v; 94 char x; 95 //scanf("%c",&x); 96 cin>>x; 97 if(x=='C'){ 98 scanf("%d%d%lld",&l,&r,&v); 99 update(v,l,r,1); 100 } 101 else{ 102 scanf("%d%d",&l,&r); 103 ll ans=query(l,r,1); 104 printf("%lld ",ans); 105 } 106 } 107 108 return 0; 109 }