• D1. Optimal Subsequences (Easy难度到hard难度)


    (color{Red}题目大意)

    (给出一个长n序列,要求每次选出一个长k的子序列,使得)
    (子序列的元素和最大且字典序最小,问第pos个元素是多少.)

    (color{orange}对于easy版本,我们可以很暴力的写)

    (直接把元素按照大小关系存进vector)

    (每次选取最大的元素,如果有多个就选最前面的那个)

    (你可能有疑问,为什么最大的元素选最前面的呢?)

    (当取完这种元素时,对答案没有影响,都要选)

    (如果没取完这种元素,那么这种元素是所取的最小元素,肯定选最前面的)

    (元素确定了,按照先后顺序排个序,就好了)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=209;
    int n,top,k,t,pos,tot;
    struct p{
    	int x,num;
    }a[209],b[209];
    bool big(p a,p b){
    	return a.x<b.x;	
    }
    bool zi(p a,p b){
    	return a.num<b.num;
    }
    vector<p>vec[maxn];
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i].x;
    		a[i].num=i;
    	}
    	sort(a+1,a+1+n,big);
    	vec[++top].push_back(a[1]);
    	for(int i=2;i<=n;i++)
    	{
    		if(a[i].x==a[i-1].x)	vec[top].push_back(a[i]);
    		else	vec[++top].push_back(a[i]);
    	}
    	for(int i=1;i<=top;i++)	sort(vec[i].begin(),vec[i].end(),zi);
    	cin>>t;
    	while(t--)
    	{
    		cin>>k>>pos;
    		tot=0;
    		int w=0;
    		for(int i=top;i>=1;i--)
    		{
    			for(int j=0;j<vec[i].size();j++)
    			{
    				b[++w]=vec[i][j];
    				if(w==k)	break;
    			}
    			if(w==0)	break;
    		}
    		sort(b+1,b+1+k,zi);
    		cout<<b[pos].x<<endl;
    	}
    }
    

    (color{Red}hard难度)

    (按照上面的的easy版本,对于每个k要取的数是固定的)

    (而且长度为k的序列只比k-1的最大序列多了一个数而已)

    (于是我们离线操作,把所有询问存起来,按照k小到大排序)

    (先处理k最小的,选出最大的k个元素,放在树状数组上标记使用过)

    (然后我们就二分出哪个点刚好使用了pos个数字,就是答案)

    (color{green}非常巧妙)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=2e5+9;
    int n,b[maxn],m,ans[maxn];
    struct p{
    	int x,num;
    	bool operator < (const p&tmp )	const{
    		return this->x==tmp.x?this->num<tmp.num:this->x>tmp.x;
    	}
    }a[maxn];
    struct quest{
    	int k,pos,index;
    	bool operator  < (const quest &tmp)	const{
    		return this->k<tmp.k;
    	}
    }q[maxn];
    class binary_tree
    {
    	private:
    		int sumn[maxn];
    		int lowbit(int x){return x&(-x);}
    	public:
    		void update(int x,int k){
    			while(x<=n)	sumn[x]+=k,x+=lowbit(x);
    		}		
    		int ask(int x){
    			int ans=0;
    			while(x)	ans+=sumn[x],x-=lowbit(x);
    			return ans;
    		}
    }tree;
    void solve()
    {
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i].x;
    		a[i].num=i;
    		b[i]=a[i].x;
    	}
    	sort(a+1,a+1+n);
    	cin>>m;
    	for(int i=1;i<=m;i++)
    	{
    		cin>>q[i].k>>q[i].pos;
    		q[i].index=i;
    	}
    	sort(q+1,q+1+m);
    	int cur=1;
    	for(int i=1;i<=m;i++)
    	{
    		for(;cur<=q[i].k;cur++)	tree.update(a[cur].num,1);
    		int l=1,r=n;
    		while(r>l)
    		{
    			int mid=l+r>>1;
    			if(tree.ask(mid)>=q[i].pos)	r=mid;
    			else	l=mid+1;
    		}
    		ans[q[i].index]=b[r];
    	}
    	for(int i=1;i<=m;i++)	cout<<ans[i]<<endl;
    }
    int main()
    {
    	solve();
    } 
    
  • 相关阅读:
    解决linux下svn update 产生Node remains in conflict的问题
    实现本地svn目录同步时,服务器的相应目录保持自动同步
    linux下搭建SVN
    linux下安装pip与pip安装
    CentOS7下将Python的版本升级为3.7
    Linux基础二:初识linux命令
    泛型数组 + 记录类型 + Json 之间的转换
    TDictionary字典 记录 的赋值。
    TDictionary字典 对象的释放。。。
    基于 Intraweb 和 JQuery 的开发套件
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12938367.html
Copyright © 2020-2023  润新知