Description
给定一个长度为n的序列,要求资瓷
- 把l到r的数字与v取max
- 把l到r的数字与v取min
输出最后结果
对于100%的数据,1≤n≤2,000,000,1≤k≤500,000。
Solution
一开始想找一道最假女选手这样的题写一写的。。
我们可以直接上线段树beats!维护最大值、次大值、最小值、次小值,就是不太好写
实际上我们可以开两棵线段树分别维护区间的上界和下界,最终遍历一次就可以了
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
const int INF=0x3f3f3f3f;
const int N=2000005;
int mx[N<<2],mn[N<<2],tgx[N<<2],tgn[N<<2];
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
void push_up(int now) {
mx[now]=std:: max(mx[now<<1],mx[now<<1|1]);
mn[now]=std:: min(mn[now<<1],mn[now<<1|1]);
}
void cmax(int &x,int v) {
(x<v)?(x=v):0;
}
void cmin(int &x,int v) {
(x>v)?(x=v):0;
}
void updx(int now,int w) {
cmax(tgx[now],w); cmax(tgn[now],w);
cmax(mx[now],w); cmax(mn[now],w);
}
void updn(int now,int w) {
cmin(tgx[now],w); cmin(tgn[now],w);
cmin(mx[now],w); cmin(mn[now],w);
}
void push_down(int now) {
if (tgx[now]!=-INF) {
int w=tgx[now]; tgx[now]=-INF;
updx(now<<1,w); updx(now<<1|1,w);
}
if (tgn[now]!=INF) {
int w=tgn[now]; tgn[now]=INF;
updn(now<<1,w); updn(now<<1|1,w);
}
}
void mMax(int now,int tl,int tr,int l,int r,int v) {
if (r<l) return ;
if (tl>=l&&tr<=r) {
updx(now,v); return ;
}
push_down(now);
int mid=(tl+tr)>>1;
mMax(now<<1,tl,mid,l,std:: min(r,mid),v);
mMax(now<<1|1,mid+1,tr,std:: max(mid+1,l),r,v);
push_up(now);
}
void mMin(int now,int tl,int tr,int l,int r,int v) {
if (r<l) return ;
if (tl>=l&&tr<=r) {
updn(now,v); return ;
}
push_down(now);
int mid=(tl+tr)>>1;
mMin(now<<1,tl,mid,l,std:: min(r,mid),v);
mMin(now<<1|1,mid+1,tr,std:: max(mid+1,l),r,v);
push_up(now);
}
void build(int now,int tl,int tr) {
tgx[now]=-INF; tgn[now]=INF;
if (tl==tr) return ;
int mid=(tl+tr)>>1;
build(now<<1,tl,mid);
build(now<<1|1,mid+1,tr);
}
void ouput(int now,int tl,int tr) {
if (tl==tr) return (void) (printf("%d\n", mx[now]));
push_down(now);
int mid=(tl+tr)>>1;
ouput(now<<1,tl,mid); ouput(now<<1|1,mid+1,tr);
push_up(now);
}
int main(void) {
int n=read(),m=read();
build(1,1,n);
for (;m--;) {
int opt=read(),l=read()+1,r=read()+1,k=read();
if (opt==1) mMax(1,1,n,l,r,k);
else mMin(1,1,n,l,r,k);
}
ouput(1,1,n);
return 0;
}