[THUPC 2024 初赛] 套娃题解
题目大意
你需要对每一个长度的区间,求出以他为长度的区间的
大致思路
有一个神奇的结论:对于点
证明&实现:我们考虑找出这些矩形的过程,可以先求出每个后缀的
于是我们可以先处理出这些矩形,长度为
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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】