CF547 B. Mike and Feet
题目传送门:https://codeforces.com/problemset/problem/547/B
题目大意:
给你一个长度为\(n\)的序列\(A\),对于一个\(k\leqslant n\),记\(B_{k,i}=\min\limits_{j=i}^{i+k-1}\{A_j\}\),记\(C_k=\max\limits_{i=1}^{n+1-k}\{B_{k,i}\}\),请求出所有的\(C_k\)
考虑按权值倒序将\(A_i\)插入到序列中,可以发现已插入的点会将序列划分为多个区间(边界点设为0和n+1),对于即将插入的多个\(A_{p_1}=A_{p_2}=...=A_{p_m}=v\),我们记\(l_{1},l_{2},...,l_{m}\)分别为包含位置\(p_i\)的区间长度,记\(MaxL_=\max\{l_i\}\),易得当\(k\leqslant MaxL\)时,\(C_k\)至少为\(v\)
故在最后,我们对\(MaxL\)求出最大的\(v\)即可
注:求区间长度可以用几乎所有的二叉平衡树
/*program from Wolfycz*/
#include<map>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Fi first
#define Se second
#define ll_inf 1e18
#define MK make_pair
#define sqr(x) ((x)*(x))
#define pii pair<int,int>
#define int_inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
template<typename T>inline T frd(T x){
int f=1; char ch=gc();
for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
template<typename T>inline T read(T x){
int f=1; char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x<0) putchar('-'),x=-x;
if (x>9) print(x/10);
putchar(x%10+'0');
}
const int N=2e5;
int A[N+10],list[N+10],Max[N+10];
vector<int>pos[N+10];
struct S1{
#define ls(x) tree[x][0]
#define rs(x) tree[x][1]
#define T(x) (rs(f[x])==x)
int tree[N+10][2],f[N+10],V[N+10],size[N+10],root,tot;
void clear(int x){ls(x)=rs(x)=f[x]=V[x]=size[x]=0,tot--;}
void update(int x){size[x]=size[ls(x)]+size[rs(x)]+1;}
void rorate(int x){
int fa=f[x],son=tree[x][T(x)^1];
tree[x][T(x)^1]=fa;
tree[fa][T(x)]=son;
if (son) f[son]=fa;
f[x]=f[fa];
if (f[x]) tree[f[x]][T(fa)]=x;
f[fa]=x;
update(fa),update(x);
}
void splay(int x){
while (f[x]){
if (f[f[x]]) T(x)==T(f[x])?rorate(f[x]):rorate(x);
rorate(x);
}
root=x;
}
void insert(int val){
V[++tot]=val;
if (!root){
size[root=tot]=1;
return;
}
int p=root;
while (true){
size[p]++;
if (val<=V[p]){
if (!ls(p)){f[ls(p)=tot]=p;break;}
else p=ls(p);
}else{
if (!rs(p)){f[rs(p)=tot]=p;break;}
else p=rs(p);
}
}
splay(tot);
}
void Delete(int x){
splay(x);
if (!(ls(x)&&rs(x))){
f[root=ls(x)+rs(x)]=0;
clear(x);
return;
}
int p=Pre();
splay(p);
size[f[rs(p)=rs(x)]=p]--;
clear(x);
}
int Find(int x,int p){
if (!p) return 0;
if (size[ls(p)]+1==x) return p;
if (x<=size[ls(p)]) return Find(x,ls(p));
return Find(x-size[ls(p)]-1,rs(p));
}
int Rnk(int val){
int p=root,res=0;
while (p){
if (val>V[p]) res+=size[ls(p)]+1,p=rs(p);
else p=ls(p);
}
return res;
}
int Pre(){
int x=ls(root);
while (rs(x)) x=rs(x);
return x;
}
int Suc(){
int x=rs(root);
while (ls(x)) x=ls(x);
return x;
}
int PreV(){return V[Pre()];}
int SucV(){return V[Suc()];}
}Splay;
int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int n=read(0);
for (int i=1;i<=n;i++) list[i]=A[i]=read(0);
sort(list+1,list+1+n);
int T=unique(list+1,list+1+n)-list-1;
for (int i=1;i<=n;i++) A[i]=lower_bound(list+1,list+1+T,A[i])-list;
for (int i=1;i<=n;i++) pos[A[i]].push_back(i);
Splay.insert(0),Splay.insert(n+1);
for (int i=1;i<=T;i++){
for (vector<int>::iterator it=pos[i].begin();it!=pos[i].end();it++){
int Rank=Splay.Rnk(*it);
Splay.splay(Splay.Find(Rank,Splay.root));
Max[i]=max(Max[i],Splay.SucV()-Splay.V[Splay.root]-1);
}
for (vector<int>::iterator it=pos[i].begin();it!=pos[i].end();it++)
Splay.insert(*it);
}
int Last=0;
for (int i=T;i;i--)
for (;Last<Max[i];Last++)
printf("%d ",list[i]);
putchar('\n');
return 0;
}