分块试水--CODEVS4927 线段树练习5
模板
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #include<stdlib.h> 5 #include<math.h> 6 //#include<bitset> 7 //#include<iostream> 8 using namespace std; 9 10 int n,m,q; 11 #define maxn 100011 12 #define maxm 361 13 #define LL long long 14 const LL inf=1e18; 15 LL a[maxn],add[maxm],be[maxm],sum[maxm],Max[maxm],Min[maxm]; bool hasbe[maxm]; 16 int bel[maxn],tot; 17 18 void down(int x) 19 { 20 int l=(x-1)*m+1,r=min(x*m,n); 21 for (int i=l;i<=r;i++) 22 { 23 if (add[x]) a[i]+=add[x]; 24 else if (hasbe[x]) a[i]=be[x]; 25 } 26 add[x]=hasbe[x]=0; 27 } 28 void up(int x) 29 { 30 int l=(x-1)*m+1,r=min(x*m,n); 31 sum[x]=0; Max[x]=-inf; Min[x]=inf; 32 for (int i=l;i<=r;i++) 33 sum[x]+=a[i],Max[x]=max(Max[x],a[i]),Min[x]=min(Min[x],a[i]); 34 } 35 void Addsingle(int x,int y,int v) 36 { 37 down(bel[x]); 38 for (int i=x;i<=y;i++) a[i]+=v; 39 up(bel[x]); 40 } 41 void Add(int x,int y,int v) 42 { 43 if (bel[x]==bel[y]) Addsingle(x,y,v); 44 else 45 { 46 int j; 47 for (j=x;bel[j]==bel[x];j++); 48 Addsingle(x,j-1,v); 49 for (j=y;bel[j]==bel[y];j--); 50 Addsingle(j+1,y,v); 51 for (int i=bel[x]+1;i<bel[y];i++) 52 { 53 if (hasbe[i]) be[i]+=v; 54 else add[i]+=v; 55 sum[i]+=1ll*m*v; 56 Max[i]+=v; Min[i]+=v; 57 } 58 } 59 } 60 void Besingle(int x,int y,int v) 61 { 62 down(bel[x]); 63 for (int i=x;i<=y;i++) a[i]=v; 64 up(bel[x]); 65 } 66 void Be(int x,int y,int v) 67 { 68 if (bel[x]==bel[y]) Besingle(x,y,v); 69 else 70 { 71 int j; 72 for (j=x;bel[j]==bel[x];j++); 73 Besingle(x,j-1,v); 74 for (j=y;bel[j]==bel[y];j--); 75 Besingle(j+1,y,v); 76 for (int i=bel[x]+1;i<bel[y];i++) 77 { 78 if (add[i]) add[i]=0; 79 hasbe[i]=1; be[i]=v; 80 sum[i]=1ll*m*v; 81 Max[i]=Min[i]=v; 82 } 83 } 84 } 85 LL qsumsingle(int x,int y) 86 { 87 LL ans=0; 88 for (int i=x;i<=y;i++) 89 { 90 if (hasbe[bel[i]]) ans+=be[bel[i]]; 91 else ans+=a[i]+add[bel[i]]; 92 } 93 return ans; 94 } 95 LL qsum(int x,int y) 96 { 97 if (bel[x]==bel[y]) return qsumsingle(x,y); 98 else 99 { 100 int j; 101 for (j=x;bel[j]==bel[x];j++); 102 LL ans=qsumsingle(x,j-1); 103 for (j=y;bel[j]==bel[y];j--); 104 ans+=qsumsingle(j+1,y); 105 for (int i=bel[x]+1;i<bel[y];i++) ans+=sum[i]; 106 return ans; 107 } 108 } 109 LL qmaxsingle(int x,int y) 110 { 111 LL ans=-inf; 112 for (int i=x;i<=y;i++) 113 { 114 if (hasbe[bel[i]]) ans=max(ans,be[bel[i]]); 115 else ans=max(ans,a[i]+add[bel[i]]); 116 } 117 return ans; 118 } 119 LL qmax(int x,int y) 120 { 121 if (bel[x]==bel[y]) return qmaxsingle(x,y); 122 else 123 { 124 int j; 125 for (j=x;bel[j]==bel[x];j++); 126 LL ans=qmaxsingle(x,j-1); 127 for (j=y;bel[j]==bel[y];j--); 128 ans=max(ans,qmaxsingle(j+1,y)); 129 for (int i=bel[x]+1;i<bel[y];i++) ans=max(ans,Max[i]); 130 return ans; 131 } 132 } 133 LL qminsingle(int x,int y) 134 { 135 LL ans=inf; 136 for (int i=x;i<=y;i++) 137 { 138 if (hasbe[bel[i]]) ans=min(ans,be[bel[i]]); 139 else ans=min(ans,a[i]+add[bel[i]]); 140 } 141 return ans; 142 } 143 LL qmin(int x,int y) 144 { 145 if (bel[x]==bel[y]) return qminsingle(x,y); 146 else 147 { 148 int j; 149 for (j=x;bel[j]==bel[x];j++); 150 LL ans=qminsingle(x,j-1); 151 for (j=y;bel[j]==bel[y];j--); 152 ans=min(ans,qminsingle(j+1,y)); 153 for (int i=bel[x]+1;i<bel[y];i++) ans=min(ans,Min[i]); 154 return ans; 155 } 156 } 157 int main() 158 { 159 scanf("%d%d",&n,&q); 160 m=(int)sqrt(n); 161 for (int i=1;i<=n;i++) bel[i]=(i-1)/m+1; 162 tot=bel[n]; 163 for (int i=1;i<=tot;i++) Max[i]=-inf,Min[i]=inf; 164 for (int i=1;i<=n;i++) 165 { 166 scanf("%lld",&a[i]); 167 sum[bel[i]]+=a[i]; 168 Max[bel[i]]=max(Max[bel[i]],a[i]); 169 Min[bel[i]]=min(Min[bel[i]],a[i]); 170 } 171 172 char c[10];int x,y,z; 173 while (q--) 174 { 175 scanf("%s%d%d",c,&x,&y); 176 if (c[0]=='a') scanf("%d",&z),Add(x,y,z); 177 else if (c[1]=='e') scanf("%d",&z),Be(x,y,z); 178 else if (c[1]=='u') printf("%lld\n",qsum(x,y)); 179 else if (c[1]=='a') printf("%lld\n",qmax(x,y)); 180 else printf("%lld\n",qmin(x,y)); 181 } 182 return 0; 183 }