[THUPC 2024 初赛] 套娃题解

题目大意

你需要对每一个长度的区间,求出以他为长度的区间的 mex 构成集合的 mex

n105

大致思路

有一个神奇的结论:对于点 (l,r)mexl,r 的矩形,其中按颜色分割得到的矩形数是 O(n) 级别的

证明&实现:我们考虑找出这些矩形的过程,可以先求出每个后缀的mex ,在考虑删点,删点过程是对lstaii 的位置和 aimin ,又由于 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;
}
posted @   hubingshan  阅读(106)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示