支持将某一区间设为x,将某一区间加x,查询区间的和。
题目为 小明学求和II
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #define mn 100001 5 #define INF -1000001 6 using namespace std; 7 8 int n,m,b[mn],t,L,R,c; 9 long long sum[30*mn],add[30*mn],set[30*mn]; 10 11 void buildtree(int k,int l,int r){ 12 set[k]=INF; 13 int mid=(l+r)/2; 14 if (l==r) sum[k]=set[k]=b[l]; 15 else{ 16 buildtree(2*k,l,mid); 17 buildtree(2*k+1,mid+1,r); 18 sum[k]=sum[2*k]+sum[2*k+1]; 19 } 20 } 21 22 inline void pushdown(int k,int l,int r){ 23 int mid=(l+r)/2; 24 if (r==l) return; 25 if (set[k]!=INF){ 26 set[2*k]=set[2*k+1]=set[k]; 27 add[2*k]=add[2*k+1]=0; 28 set[k]=INF; 29 } 30 add[2*k]+=add[k]; 31 add[2*k+1]+=add[k]; 32 add[k]=0; 33 } 34 35 inline void maintain(int k,int l,int r){ 36 if (set[k]!=INF) sum[k]=(set[k]+add[k])*(r-l+1); 37 else sum[k]=sum[2*k]+sum[2*k+1]+add[k]*(r-l+1); 38 } 39 40 void updateadd(int k,int l,int r){ 41 int mid=(l+r)/2; 42 if (L<=l && R>=r) add[k]+=c; 43 else{ 44 pushdown(k,l,r); 45 if (L<=mid) updateadd(2*k,l,mid);else maintain(2*k,l,mid); 46 if (R>mid) updateadd(2*k+1,mid+1,r);else maintain(2*k+1,mid+1,r); 47 } 48 maintain(k,l,r); 49 } 50 51 void updateset(int k,int l,int r){ 52 int mid=(l+r)/2; 53 if (L<=l && R>=r){ 54 set[k]=c; 55 add[k]=0; 56 }else{ 57 pushdown(k,l,r); 58 if (L<=mid) updateset(2*k,l,mid);else maintain(2*k,l,mid); 59 if (R>mid) updateset(2*k+1,mid+1,r);else maintain(2*k+1,mid+1,r); 60 } 61 maintain(k,l,r); 62 } 63 64 long long query(int k,int l,int r){ 65 long long ans=0; 66 int mid=(l+r)/2; 67 if (L<=l && R>=r) return sum[k]; 68 else if (set[k]!=INF) return (long long)(set[k]+add[k])*(min(R,r)-max(L,l)+1); 69 else{ 70 if (L<=mid) ans+=query(2*k,l,mid); 71 if (R>mid) ans+=query(2*k+1,mid+1,r); 72 ans+=add[k]*(min(R,r)-max(L,l)+1); 73 return ans; 74 } 75 } 76 77 int main(){ 78 scanf("%d%d",&n,&m); 79 for (int i=1;i<=n;i++) scanf("%d",&b[i]); 80 buildtree(1,1,n); 81 for (int i=1;i<=m;i++){ 82 scanf("%d",&t); 83 if (t==1){ 84 scanf("%d%d%d",&L,&R,&c); 85 updateadd(1,1,n); 86 }else if (t==2){ 87 scanf("%d%d%d",&L,&R,&c); 88 updateset(1,1,n); 89 }else{ 90 scanf("%d%d",&L,&R); 91 printf("%lld\n",query(1,1,n)); 92 } 93 } 94 return 0; 95 }