zoukankan      html  css  js  c++  java
  • CF547 B. Mike and Feet

    题目传送门:https://codeforces.com/problemset/problem/547/B

    题目大意:
    给你一个长度为(n)的序列(A),对于一个(kleqslant n),记(B_{k,i}=minlimits_{j=i}^{i+k-1}{A_j}),记(C_k=maxlimits_{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}),易得当(kleqslant 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('
    ');
    	return 0;
    }
    
    作者:Wolfycz
    本文版权归作者和博客园共有,欢迎转载,但必须在文章开头注明原文出处,否则保留追究法律责任的权利
  • 相关阅读:
    南阳oj 814 又见拦截导弹
    南阳 zb的生日和邮票分你一般(01背包思路)
    导弹拦截(最长下降子序列)变形
    控件绝对定位函数
    小玩意
    java获取本机所有可用字体
    按键监听类KeyListener及适配器改良方案
    编译php-memcached扩展
    Memcached安装,启动,连接
    Apache配置虚拟主机
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/14958710.html
Copyright © 2011-2022 走看看