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要取的数是固定的\)

扫描二维码关注公众号,回复: 11248816 查看本文章

\(而且长度为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();
} 

猜你喜欢

转载自www.cnblogs.com/iss-ue/p/12938367.html
今日推荐