分块试水--CODEVS4927 线段树练习5

Posted Blue233333

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分块试水--CODEVS4927 线段树练习5相关的知识,希望对你有一定的参考价值。

模板

技术分享图片
  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 }
View Code

 

以上是关于分块试水--CODEVS4927 线段树练习5的主要内容,如果未能解决你的问题,请参考以下文章

codevs 4927 线段树练习5

codevs 4927 线段树练习5

CodeVS 4927-线段树练习5

codevs 4927 线段树练习5 线段树基本操作模板

codevs 4927 线段树练习5

codevs 4927 线段树练习5