「杂题乱刷2」CF1227D2

题目链接

CF1227D1 Optimal Subsequences (Hard Version) *1600

CF1227D2 Optimal Subsequences (Hard Version) *1800

解题思路

本篇题解分 D1,D2 两个部分来写。

D1 sol:

我们容易发现有以下两点性质:

  • 要想子序列和最大,必须选择前 \(k\) 大的数字。

  • 比第 \(k\) 大的数字还要大的数字是必须取的。

然后容易发现,我们能改变序列的差异只能是改变所有值为第 \(k\) 大的数的选取情况。

那么显然,选取最前面的数是最优的。

直接暴力选取即可,时间复杂度 \(O(nm + n \log n)\)

D2 sol:

根据 D1 的思路,我们需要优化掉这个暴力。

考虑将询问离线,并按照查询的序列长度从小到大进行排序。

这样我们就只需要维护加数操作和目前加的数字有几个值为第 \(k\) 大的数字即可。

加数操作和查询操作我们可以使用优先队列和树状数组维护。

时间复杂度 \(O(m \log^2 n)\)

参考代码

D1 code:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
//#define map unordered_map
#define re register
#define ll long long
#define forl(i,a,b) for(re ll i=a;i<=b;i++)
#define forr(i,a,b) for(re ll i=a;i>=b;i--)
#define forll(i,a,b,c) for(re ll i=a;i<=b;i+=c)
#define forrr(i,a,b,c) for(re ll i=a;i>=b;i-=c)
#define pii pair<ll,ll>
#define mid ((l+r)>>1)
#define lowbit(x) (x&-x)
#define pb push_back
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl '\n'
#define QwQ return 0;
#define db long double
#define ull unsigned long long
#define lcm(x,y) (1ll*(x)/__gcd(x,y)*(y))
#define Sum(x,y) (1ll*((x)+(y))*((y)-(x)+1)/2)
#define x first
#define y second
#define aty cout<<"Yes\n";
#define atn cout<<"No\n";
#define cfy cout<<"YES\n";
#define cfn cout<<"NO\n";
#define xxy cout<<"yes\n";
#define xxn cout<<"no\n";
#define printcf(x) x?cout<<"YES\n":cout<<"NO\n";
#define printat(x) x?cout<<"Yes\n":cout<<"No\n";
#define printxx(x) x?cout<<"yes\n":cout<<"no\n";
#define maxqueue priority_queue<ll>
#define minqueue priority_queue<ll,vector<ll>,greater<ll>>
#define bug cout<<"---------------------------------------\n";
ll _t_;
void _clear(){}
ll n,q;
ll a[100010],b[100010];
ll k;
map<ll,ll>mp,mp2;
bool cmp(ll x,ll y){
	return x>y;
}
void solve()
{
    _clear();
	cin>>n;
	forl(i,1,n)
		cin>>a[i],mp[a[i]]=1;
	for(auto i:mp)
		mp2[i.x]=++k;
	for(auto i:mp2)
		mp[i.y]=i.x;
	forl(i,1,n)
		a[i]=mp2[a[i]],b[i]=a[i];
	sort(b+1,b+1+n,cmp);
	cin>>q;
	while(q--)
	{
		ll x,y;
		cin>>x>>y;
		ll sum=0,num=b[x];
		ll last=0,L=x;
		while(b[L]==num)
			L--,last++;
		forl(i,1,n)
		{
			sum+=a[i]>num;
			if(a[i]==num && last)
				last--,sum++;
			if(sum==y)
			{
				cout<<mp[a[i]]<<endl;
				break;
			}
		}
	}
}
int main()
{
//    freopen("tst.txt","r",stdin);
//    freopen("sans.txt","w",stdout);
    IOS;
    _t_=1;
 //   cin>>_t_;
    while(_t_--)
        solve();
    QwQ;
}

D2 code:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
//#define map unordered_map
#define re register
#define ll long long
#define forl(i,a,b) for(re ll i=a;i<=b;i++)
#define forr(i,a,b) for(re ll i=a;i>=b;i--)
#define forll(i,a,b,c) for(re ll i=a;i<=b;i+=c)
#define forrr(i,a,b,c) for(re ll i=a;i>=b;i-=c)
#define pii pair<ll,ll>
#define mid ((l+r)>>1)
#define lowbit(x) (x&-x)
#define pb push_back
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl '\n'
#define QwQ return 0;
#define db long double
#define ull unsigned long long
#define lcm(x,y) (1ll*(x)/__gcd(x,y)*(y))
#define Sum(x,y) (1ll*((x)+(y))*((y)-(x)+1)/2)
#define x first
#define y second
#define aty cout<<"Yes\n";
#define atn cout<<"No\n";
#define cfy cout<<"YES\n";
#define cfn cout<<"NO\n";
#define xxy cout<<"yes\n";
#define xxn cout<<"no\n";
#define printcf(x) x?cout<<"YES\n":cout<<"NO\n";
#define printat(x) x?cout<<"Yes\n":cout<<"No\n";
#define printxx(x) x?cout<<"yes\n":cout<<"no\n";
#define maxqueue priority_queue<pii>
#define minqueue priority_queue<pii,vector<pii>,greater<pii>>
#define bug cout<<"---------------------------------------\n";
template<typename T1,typename T2>bool Max(T1&x,T2 y){if(y>x)return x=y,1;return 0;}
template<typename T1,typename T2>bool Min(T1&x,T2 y){if(y<x)return x=y,1;return 0;}
ll _t_;
void _clear(){}
ll n,Q;
ll a[1000010],b[1000010];
ll k;
map<ll,ll>mp,mp2;
bool cmp(ll x,ll y){
	return x>y;
}
struct node{
	ll x,y,id;
}q[1000010];
bool pmc(node x,node y){
	return x.x<y.x;
}
maxqueue qu;
ll ans[1000010];
ll tree[1000010];
ll qwq[1000010];
void add(ll x,ll y){
	for(;x<=2e5+5;x+=lowbit(x))
		tree[x]+=y;
}
ll query(ll x)
{
	ll sum=0;
	for(;x;x-=lowbit(x))
		sum+=tree[x];
	return sum;
}
void solve()
{
    _clear();
	cin>>n;
	forl(i,1,n)
		cin>>a[i],mp[a[i]]=1;
	for(auto i:mp)
		mp2[i.x]=++k;
	for(auto i:mp2)
		mp[i.y]=i.x;
	forl(i,1,n)
		a[i]=mp2[a[i]],b[i]=a[i];
	sort(b+1,b+1+n,cmp);
	forl(i,1,n)
		qu.push({a[i],-i});
	cin>>Q;
	forl(i,1,Q)
		cin>>q[i].x>>q[i].y,q[i].id=i;
	sort(q+1,q+1+Q,pmc);
	ll sz=0;
	forl(i,1,Q)
	{
		while(sz<q[i].x)
		{
			pii now=qu.top();
			qu.pop();
			add(-now.y,1);
		//	add(-now.y+1,-1);
			sz++;
		}
		ll L=1,R=n;
		while(L<R)
		{
			ll Mid=(L+R)/2;
			if(query(Mid)<q[i].y)
				L=Mid+1;
			else
				R=Mid;
		}
		ans[q[i].id]=mp[a[L]];
		qwq[q[i].id]=L;
	}
	forl(i,1,Q)
//		cout<<qwq[i]<<':',
		cout<<ans[i]<<endl;
}
int main()
{
//    freopen("tst.txt","r",stdin);
//    freopen("sans.txt","w",stdout);
    IOS;
    _t_=1;
 //   cin>>_t_;
    while(_t_--)
        solve();
    QwQ;
}
posted @ 2024-10-04 17:23  wangmarui  阅读(2)  评论(0编辑  收藏  举报