• CF-Technocup3 D Optimal Subsequences


    D Optimal Subsequences

    http://codeforces.com/contest/1227/problem/D2
    显然,每次求的k一定是这个序列从大到小排序后前k大的元素。
    考虑如何做才能使其字典序最小。我们设p为第k大的元素。
    首先,这k个数是确定的。
    其次,对于比p大的所有元素,他们是必须选的。
    所以,欲使这个序列字典序最小,其实就是让所有p出现的位置
    尽量靠前。
    那做法就很显然了:先离散化,搞出来一个相对排名,用主席树
    维护相对排名。每次查询,二分答案,check就查一下root[1]到
    root[mid]中权值排名大于p的排名+min(p的上限个数,root[1]
    到root[mid]中p的出现次数)和pos的关系就好。
    其实离线搞更方便一些,也不用可持久化。。
    上代码

    #include<bits/stdc++.h>
    using namespace std;
    #define re register int
    #define F(x,y,z) for(re x=y;x<=z;x++)
    #define FOR(x,y,z) for(re x=y;x>=z;x--)
    typedef long long ll;
    #define I inline void
    #define IN inline int
    I read(int &res){
    	res=0;re g=1;register char ch=getchar();
    	while(!isdigit(ch)){
    		if(ch=='-')g=-1;
    		ch=getchar();
    	}
    	while(isdigit(ch)){
    		res=(res<<3)+(res<<1)+(ch^48);
    		ch=getchar();
    	}
    	res*=g;
    }
    struct P{
    	int w,id,v;
    	friend bool operator < (P x,P y){
    		return x.w>y.w;
    	}
    }p[202000];
    struct Tree{
    	int lc,rc,w;
    }t[6060000];
    #define L t[k].lc
    #define R t[k].rc
    int n,m,tot,X,Y,sum,pos,lim,a[202000],b[202000],f[202000],len[202000],root[202000];
    I modi(int &k,int k1,int l,int r,int x){
    	k=++tot;
    	L=t[k1].lc;R=t[k1].rc;t[k].w=t[k1].w;
    	if(l==r){
    		t[k].w++;
    		return;
    	}
    	re mid=(l+r)>>1;
    	if(x<=mid)modi(L,t[k1].lc,l,mid,x);
    	else modi(R,t[k1].rc,mid+1,r,x);
    	t[k].w=t[L].w+t[R].w;
    }
    IN ques(int k,int l,int r,int x,int y){
    	if(x>r||y<l)return 0;
    	if(x<=l&&r<=y)return t[k].w;
    	re mid=(l+r)>>1;
    	return ques(L,l,mid,x,y)+ques(R,mid+1,r,x,y);
    }
    IN divided(int x,int y){
    	if(x==y)return x;
    	re mid=(x+y)>>1;
    	//cout<<ques(root[mid],1,sum,1,pos)<<"!"<<endl;
    	if(ques(root[mid],1,sum,1,pos-1)+min(ques(root[mid],1,sum,pos,pos),lim)>=Y)y=mid;
    	else x=mid+1;
    	return divided(x,y);
    }
    int main(){
    	read(n);
    	F(i,1,n){
    		read(a[i]);
    		p[i].w=a[i];
    		p[i].id=i;
    	}
    	sort(p+1,p+1+n);
    	m=0;
    	p[0].w=p[1].w+1;
    	f[0]=0;
    	F(i,1,n){
    		if(p[i].w!=p[i-1].w)m++,f[m]=i;
    		b[p[i].id]=m;
    		p[i].v=m;
    	}
    	tot=0;
    	sum=m;
    	//cout<<sum<<endl;
    	F(i,1,n){
    		modi(root[i],root[i-1],1,sum,b[i]);
    	}
    	read(m);
    	while(m--){
    		read(X);read(Y);
    		pos=p[X].v;lim=X-f[pos]+1;
    		//cout<<pos<<" ";
    		int P=divided(1,n);
    		//cout<<P<<" ";
    		cout<<a[P]<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    MySQL基本命令总结
    B+树
    5.Flask-Migrate
    Tornado入门五
    Django之数据库表的单表查询
    MySQL表完整性约束
    MysQL表相关操作
    MySQL库相关操作
    MySQL创建用户+授权+备份
    公司 邮件 翻译 培训 6 长难句
  • 原文地址:https://www.cnblogs.com/Purple-wzy/p/11938092.html
Copyright © 2020-2023  润新知