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;
}
posted @ 2021-07-01 14:47  Wolfycz  阅读(40)  评论(0编辑  收藏  举报