题解 P5251 【[LnOI2019]第二代图灵机】
数据结构套路题,就是用的数据结构好多。。。
树状数组维护区间和
线段树维护区间最大值
ODT 维护区间染色信息
然后把三个板子放上来再写一下询问就好了
话说不知道
//by Judge
#include<set>
#include<cstring>
#include<iostream>
#define IT std::set<node>::iterator
const int inf=2e9+7;
const int M=1e5+3;
typedef int arr[M];
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
inline void cmax(int& a,int b){if(a<b)a=b;}
inline void cmin(int& a,int b){if(a>b)a=b;}
inline int Max(int a,int b){return a>b?a:b;}
inline int read(){ int x=0,f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} char sr[1<<21],z[20];int C=-1,Z;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
inline void print(int x,char chr='\n'){
if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]=chr;
} int n,m,q; arr ap,f,w; int t[M<<2];
namespace ODT{
struct node{ int l,r; mutable int v;
node(int L,int R=-1,int V=0){l=L,r=R,v=V;}
bool operator <(const node& b)const{return l<b.l;}
}; std::set<node> s;
inline IT split(int pos){ IT it=s.lower_bound(node(pos));
if(it!=s.end()&&it->l==pos) return it; --it;
node lit=node(it->l,pos-1,it->v),rit=node(pos,it->r,it->v);
s.erase(it),s.insert(lit); return s.insert(rit).first;
}
inline void assign(int l,int r,int val=0){
IT rit=split(r+1),lit=split(l);
s.erase(lit,rit),s.insert(node(l,r,val));
}
} using namespace ODT;
namespace seg_tree{
#define ls k<<1
#define rs k<<1|1
#define mid (l+r>>1)
#define lson ls,l,mid
#define rson rs,mid+1,r
#define lowbit(x) (x&-x)
void update(int k,int l,int r,int x,int v){ if(l==r) return t[k]=v,void();
if(x<=mid) update(lson,x,v); else update(rson,x,v); t[k]=Max(t[ls],t[rs]);
}
int query(int k,int l,int r,int L,int R){
if(L>r||l>R) return 0; if(L<=l&&r<=R) return t[k];
return Max(query(lson,L,R),query(rson,L,R));
}
} using namespace seg_tree;
namespace BIT{
inline void update(int x,int v){for(;x<=n;x+=lowbit(x)) f[x]+=v;}
inline int query(int x,int s=0){for(;x;x^=lowbit(x)) s+=f[x]; return s;}
inline int ask(int l,int r){return query(r)-query(l-1);}
} using namespace BIT;
inline int query1(int l,int r){
int ans=inf,lef; memset(ap,0,sizeof ap);
IT rit=split(r+1),lit=split(l),L,R; --lit;
for(L=R=lit,lef=m;R!=rit;){
if(L!=lit) --ap[L->v],lef+=!ap[L->v];
for(++L;lef&&R!=rit;)++R,lef-=!ap[R->v],++ap[R->v];
if(R==rit) break;
for(;!lef&&L!=R;++L) --ap[L->v],lef+=!ap[L->v];
if(lef) --L,++ap[L->v],--lef;
cmin(ans,ask(L->r,R->l));
} return ans;
}
inline int query2(int l,int r){
memset(ap,0,sizeof ap);
int ans=query(1,1,n,l,r);
IT rit=split(r+1),lit=split(l),L,R;
for(L=R=lit;R!=rit;++R){ ++ap[R->v];
for(;L!=R&&ap[R->v]>1;++L) --ap[L->v];
if(L!=R) cmax(ans,ask(L->r,R->l));
for(;L!=R&&R->l!=R->r;++L) --ap[L->v];
} return ans;
}
int main(){
n=read(),q=read(),m=read();
s.insert(node(0,0,-1));
for(int i=1,x;i<=n;++i) x=read(),
update(i,x),update(1,1,n,i,x);
for(int i=1,x;i<=n;++i) x=read(),
s.insert(node(i,i,x));
for(int op,l,r,x,ans;q;--q){ op=read();
if(op==1) l=read(),r=read(),
update(l,r-ask(l,l)),update(1,1,n,l,r);
else if(op==2) l=read(),r=read(),
x=read(),assign(l,r,x);
else if(op==3) l=read(),r=read(),
ans=query1(l,r),print(ans==inf?-1:ans);
else l=read(),r=read(),print(query2(l,r));
} return Ot(),0;
}