[THUPC 2024 初赛] 套娃题解
题目大意
你需要对每一个长度的区间,求出以他为长度的区间的 \(mex\) 构成集合的 \(mex\)
\(n\le10^5\)
大致思路
有一个神奇的结论:对于点 \((l,r)\) 为 \(mex_{l,r}\) 的矩形,其中按颜色分割得到的矩形数是 \(O(n)\) 级别的
证明&实现:我们考虑找出这些矩形的过程,可以先求出每个后缀的\(mex\) ,在考虑删点,删点过程是对\(lst_{a_i}\sim i\) 的位置和 \(a_i\) 取 \(min\) ,又由于 \(mex\) 序列是单调不增的,于是最多只会改变一段后缀,前面不会改变,所以每次操作只会新增 \(1\) 个区间,实现同理用\(odt\) 维护即可
于是我们可以先处理出这些矩形,长度为 \(l\) 的区间对应的就是,截距为 \(l\) ,斜率为 \(1\) 的直线,用扫描线维护就行了
code
#include<bits/stdc++.h>
using namespace std;
#define N 1000005
int n,tot,top;
int a[N],ge[N],me[N],lst[N],u[N],pos[N];
struct B{
int l,r,h,col;
bool operator < (const B &x)const{
return l<x.l;
}
};
struct A{
int l1,l2,r1,r2,col;
}d[N];
struct AA{
int x,col,y;
}q[N];
bool cmp(AA a,AA b){
return a.x<b.x;
}
void build(int p,int l,int r){
if(l==r){
me[p]=l;
return ;
}
int mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
me[p]=min(me[p*2],me[p*2+1]);
}
void jia(int p,int l,int r,int x,int y){
if(l==r){
ge[p]+=y;
if(!ge[p]) me[p]=l;
else me[p]=n+1;
return ;
}
int mid=(l+r)>>1;
if(x<=mid) jia(p*2,l,mid,x,y);
else jia(p*2+1,mid+1,r,x,y);
me[p]=min(me[p*2],me[p*2+1]);
}
set<B> qq;
void del(int i){
auto it=qq.end();it--;
B num=*it;
qq.erase(it);
int l=num.l,r=num.r-1;
d[++tot]={i,i,i,num.h,num.col};
if(l<=r) qq.insert({l,r,num.h,num.col});
l=lst[i]+1,r=l-1;
while(!qq.empty()){
it=qq.upper_bound({r+1,n+1,0,0}),it--;
num=*it;
if(num.r<l||num.col<=a[i]) break;
qq.erase(it);
r=num.r;
if(num.l<l){
d[++tot]={l,num.r,i,num.h,num.col};
qq.insert({num.l,l-1,num.h,num.col});
}
else d[++tot]={num.l,num.r,i,num.h,num.col};
}
if(l<=r) qq.insert({l,r,i-1,a[i]});
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=n,cnt=0;i>=1;i--){
u[a[i]]++;
while(u[cnt]) cnt++;
qq.insert({i,i,n,cnt});
}
for(int i=1;i<=n;i++) lst[i]=pos[a[i]],pos[a[i]]=i;
for(int i=n;i>=1;i--) del(i);
for(int i=1;i<=tot;i++) q[++top]={d[i].r1-d[i].l2+1,d[i].col,1},q[++top]={d[i].r2-d[i].l1+2,d[i].col,-1};
sort(q+1,q+1+top,cmp);
build(1,0,n);
for(int i=1,j=1;i<=n;i++){
while(j<=top&&q[j].x<=i) jia(1,0,n,q[j].col,q[j].y),j++;
printf("%d ",me[1]);
}
return 0;
}

浙公网安备 33010602011771号