(WC2016模拟十一)【BZOJ4695】最假女选手
ps:好久没更博啦……这几天连着有模拟赛,等初赛前后休息的时候来疯狂补坑吧……顺便补一下前面的数论啥的?
题解:
mdzz我场上写了个15分暴力长度跟标算差不多。。。
线段树大法好啊!这题听说很多人做过,是吉利线段树的模板题。
为什么要叫吉利线段树呢?当然是因为大名鼎鼎的吉老(si)师(ji)啦~~Orzjry
感兴趣的同学可以搜吉老师的2016年国家集训队论文——《区间最值操作与历史最值问题》
当然吉老师有个通(jiu)俗(tiao)易(ke)懂(lian)的课件--->Segment tree Beats!
随手一打就是200行5K+
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<queue>
7 #define inf 1000000000
8 #define eps 1e-9
9 using namespace std;
10 typedef long long ll;
11 struct node{
12 ll v;
13 int mx,mn,mmx,mmn,mxn,mnn,laz;
14 }t[2500001];
15 int n,m,op,l,r,x;
16 ll num[500001];
17 void pushup(int u){
18 int ls=u*2,rs=u*2+1;
19 t[u].v=t[ls].v+t[rs].v;
20 if(t[ls].mx>t[rs].mx){
21 t[u].mx=t[ls].mx;
22 t[u].mxn=t[ls].mxn;
23 t[u].mmx=max(t[ls].mmx,t[rs].mx);
24 }
25 if(t[ls].mx<t[rs].mx){
26 t[u].mx=t[rs].mx;
27 t[u].mxn=t[rs].mxn;
28 t[u].mmx=max(t[rs].mmx,t[ls].mx);
29 }
30 if(t[ls].mx==t[rs].mx){
31 t[u].mx=t[ls].mx;
32 t[u].mxn=t[ls].mxn+t[rs].mxn;
33 t[u].mmx=max(t[ls].mmx,t[rs].mmx);
34 }
35 if(t[ls].mn<t[rs].mn){
36 t[u].mn=t[ls].mn;
37 t[u].mnn=t[ls].mnn;
38 t[u].mmn=min(t[ls].mmn,t[rs].mn);
39 }
40 if(t[ls].mn>t[rs].mn){
41 t[u].mn=t[rs].mn;
42 t[u].mnn=t[rs].mnn;
43 t[u].mmn=min(t[rs].mmn,t[ls].mn);
44 }
45 if(t[ls].mn==t[rs].mn){
46 t[u].mn=t[ls].mn;
47 t[u].mnn=t[ls].mnn+t[rs].mnn;
48 t[u].mmn=min(t[ls].mmn,t[rs].mmn);
49 }
50 }
51 void pd(int u,int l,int r){
52 int ls=u*2,rs=u*2+1;
53 if(t[u].laz){
54 int mid=(l+r)/2;
55 t[ls].v+=t[u].laz*(mid-l+1);
56 t[ls].laz+=t[u].laz;
57 t[ls].mx+=t[u].laz;
58 t[ls].mmx+=t[u].laz;
59 t[ls].mn+=t[u].laz;
60 t[ls].mmn+=t[u].laz;
61 t[rs].v+=t[u].laz*(r-mid);
62 t[rs].laz+=t[u].laz;
63 t[rs].mx+=t[u].laz;
64 t[rs].mmx+=t[u].laz;
65 t[rs].mn+=t[u].laz;
66 t[rs].mmn+=t[u].laz;
67 t[u].laz=0;
68 }
69 if(t[ls].mx>t[u].mx){
70 if(t[ls].mn==t[ls].mx)t[ls].mn=t[u].mx;
71 if(t[ls].mmn==t[ls].mx)t[ls].mmn=t[u].mx;
72 t[ls].v+=1ll*(t[u].mx-t[ls].mx)*t[ls].mxn;
73 t[ls].mx=t[u].mx;
74 }
75 if(t[rs].mx>t[u].mx){
76 if(t[rs].mn==t[rs].mx)t[rs].mn=t[u].mx;
77 if(t[rs].mmn==t[rs].mx)t[rs].mmn=t[u].mx;
78 t[rs].v+=1ll*(t[u].mx-t[rs].mx)*t[rs].mxn;
79 t[rs].mx=t[u].mx;
80 }
81 if(t[ls].mn<t[u].mn){
82 if(t[ls].mx==t[ls].mn)t[ls].mx=t[u].mn;
83 if(t[ls].mmx==t[ls].mn)t[ls].mmx=t[u].mn;
84 t[ls].v+=1ll*(t[u].mn-t[ls].mn)*t[ls].mnn;
85 t[ls].mn=t[u].mn;
86 }
87 if(t[rs].mn<t[u].mn){
88 if(t[rs].mx==t[rs].mn)t[rs].mx=t[u].mn;
89 if(t[rs].mmx==t[rs].mn)t[rs].mmx=t[u].mn;
90 t[rs].v+=1ll*(t[u].mn-t[rs].mn)*t[rs].mnn;
91 t[rs].mn=t[u].mn;
92 }
93 }
94 void build(int l,int r,int u){
95 if(l==r){
96 t[u].v=t[u].mx=t[u].mn=num[l];
97 t[u].mxn=t[u].mnn=1;
98 t[u].mmx=-inf;
99 t[u].mmn=inf;
100 return;
101 }
102 int mid=(l+r)/2;
103 build(l,mid,u*2);
104 build(mid+1,r,u*2+1);
105 pushup(u);
106 }
107 void updata1(int l,int r,int u,int L,int R,int x){
108 if(L<=l&&r<=R){
109 t[u].v+=1ll*x*(r-l+1);
110 t[u].mx+=x;
111 t[u].mmx+=x;
112 t[u].mn+=x;
113 t[u].mmn+=x;
114 t[u].laz+=x;
115 return;
116 }
117 int mid=(l+r)/2;
118 pd(u,l,r);
119 if(L<=mid)updata1(l,mid,u*2,L,R,x);
120 if(mid<R)updata1(mid+1,r,u*2+1,L,R,x);
121 pushup(u);
122 }
123 void updata2(int l,int r,int u,int L,int R,int x){
124 if(t[u].mn>=x)return;
125 if(L<=l&&r<=R&&t[u].mmn>x){
126 if(t[u].mx==t[u].mn)t[u].mx=x;
127 if(t[u].mmx==t[u].mn)t[u].mmx=x;
128 t[u].v+=1ll*(x-t[u].mn)*t[u].mnn;
129 t[u].mn=x;
130 return;
131 }
132 int mid=(l+r)/2;
133 pd(u,l,r);
134 if(L<=mid)updata2(l,mid,u*2,L,R,x);
135 if(mid<R)updata2(mid+1,r,u*2+1,L,R,x);
136 pushup(u);
137 }
138 void updata3(int l,int r,int u,int L,int R,int x){
139 if(t[u].mx<=x)return;
140 if(L<=l&&r<=R&&t[u].mmx<x){
141 if(t[u].mn==t[u].mx)t[u].mn=x;
142 if(t[u].mmn==t[u].mx)t[u].mmn=x;
143 t[u].v+=1ll*(x-t[u].mx)*t[u].mxn;
144 t[u].mx=x;
145 return;
146 }
147 int mid=(l+r)/2;
148 pd(u,l,r);
149 if(L<=mid)updata3(l,mid,u*2,L,R,x);
150 if(mid<R)updata3(mid+1,r,u*2+1,L,R,x);
151 pushup(u);
152 }
153 ll query1(int l,int r,int u,int L,int R){
154 if(L<=l&&r<=R){
155 return t[u].v;
156 }
157 int mid=(l+r)/2;
158 ll ret=0;
159 pd(u,l,r);
160 if(L<=mid)ret+=query1(l,mid,u*2,L,R);
161 if(mid<R)ret+=query1(mid+1,r,u*2+1,L,R);
162 //pushup(u);
163 return ret;
164 }
165 int query2(int l,int r,int u,int L,int R){
166 if(L<=l&&r<=R){
167 return t[u].mx;
168 }
169 int mid=(l+r)/2,ret=-inf;
170 pd(u,l,r);
171 if(L<=mid)ret=max(ret,query2(l,mid,u*2,L,R));
172 if(mid<R)ret=max(ret,query2(mid+1,r,u*2+1,L,R));
173 //pushup(u);
174 return ret;
175 }
176 int query3(int l,int r,int u,int L,int R){
177 if(L<=l&&r<=R){
178 return t[u].mn;
179 }
180 int mid=(l+r)/2,ret=inf;
181 pd(u,l,r);
182 if(L<=mid)ret=min(ret,query3(l,mid,u*2,L,R));
183 if(mid<R)ret=min(ret,query3(mid+1,r,u*2+1,L,R));
184 //pushup(u);
185 return ret;
186 }
187 int main(){
188 scanf("%d",&n);
189 for(int i=1;i<=n;i++){
190 scanf("%lld",&num[i]);
191 }
192 build(1,n,1);
193 scanf("%d",&m);
194 for(int i=1;i<=m;i++){
195 scanf("%d%d%d",&op,&l,&r);
196 if(op<=3)scanf("%d",&x);
197 if(op==1)updata1(1,n,1,l,r,x);
198 if(op==2)updata2(1,n,1,l,r,x);
199 if(op==3)updata3(1,n,1,l,r,x);
200 if(op==4)printf("%lld\n",query1(1,n,1,l,r));
201 if(op==5)printf("%d\n",query2(1,n,1,l,r));
202 if(op==6)printf("%d\n",query3(1,n,1,l,r));
203 }
204 return 0;
205 }