码迷,mamicode.com
首页 > 编程语言 > 详细

cf 602 D 二分+树状数组

时间:2019-12-05 22:19:38      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:cto   query   oss   preview   elements   OWIN   c++   and   back   

This is the harder version of the problem. In this version, 1n,m21051≤n,m≤2⋅105. You can hack this problem if you locked it. But you can hack the previous problem only if you locked both problems.

You are given a sequence of integers a=[a1,a2,,an]a=[a1,a2,…,an] of length nn. Its subsequence is obtained by removing zero or more elements from the sequence aa (they do not necessarily go consecutively). For example, for the sequence a=[11,20,11,33,11,20,11]a=[11,20,11,33,11,20,11]:

  • [11,20,11,33,11,20,11][11,20,11,33,11,20,11], [11,20,11,33,11,20][11,20,11,33,11,20], [11,11,11,11][11,11,11,11], [20][20], [33,20][33,20] are subsequences (these are just some of the long list);
  • [40][40], [33,33][33,33], [33,20,20][33,20,20], [20,20,11,11][20,20,11,11] are not subsequences.

Suppose that an additional non-negative integer kk (1kn1≤k≤n) is given, then the subsequence is called optimal if:

  • it has a length of kk and the sum of its elements is the maximum possible among all subsequences of length kk;
  • and among all subsequences of length kk that satisfy the previous item, it is lexicographically minimal.

Recall that the sequence b=[b1,b2,,bk]b=[b1,b2,…,bk] is lexicographically smaller than the sequence c=[c1,c2,,ck]c=[c1,c2,…,ck] if the first element (from the left) in which they differ less in the sequence bb than in cc. Formally: there exists tt (1tk1≤t≤k) such that b1=c1b1=c1, b2=c2b2=c2, ..., bt1=ct1bt−1=ct−1 and at the same time bt<ctbt<ct. For example:

  • [10,20,20][10,20,20] lexicographically less than [10,21,1][10,21,1],
  • [7,99,99][7,99,99] is lexicographically less than [10,21,1][10,21,1],
  • [10,21,0][10,21,0] is lexicographically less than [10,21,1][10,21,1].

You are given a sequence of a=[a1,a2,,an]a=[a1,a2,…,an] and mm requests, each consisting of two numbers kjkj and posjposj (1kn1≤k≤n, 1posjkj1≤posj≤kj). For each query, print the value that is in the index posjposj of the optimal subsequence of the given sequence aa for k=kjk=kj.

For example, if n=4n=4, a=[10,20,30,20]a=[10,20,30,20], kj=2kj=2, then the optimal subsequence is [20,30][20,30] — it is the minimum lexicographically among all subsequences of length 22 with the maximum total sum of items. Thus, the answer to the request kj=2kj=2, posj=1posj=1 is the number 2020, and the answer to the request kj=2kj=2, posj=2posj=2 is the number 3030.

Input

The first line contains an integer nn (1n21051≤n≤2⋅105) — the length of the sequence aa.

The second line contains elements of the sequence aa: integer numbers a1,a2,,ana1,a2,…,an (1ai1091≤ai≤109).

The third line contains an integer mm (1m21051≤m≤2⋅105) — the number of requests.

The following mm lines contain pairs of integers kjkj and posjposj (1kn1≤k≤n, 1posjkj1≤posj≤kj) — the requests.

Output

Print mm integers r1,r2,,rmr1,r2,…,rm (1rj1091≤rj≤109) one per line: answers to the requests in the order they appear in the input. The value of rjrjshould be equal to the value contained in the position posjposj of the optimal subsequence for k=kjk=kj.

Examples
input
3
10 20 10
6
1 1
2 1
2 2
3 1
3 2
3 3
output
20
10
20
10
20
10
input
7
1 2 1 3 1 2 1
9
2 1
2 2
3 1
3 2
3 3
1 1
7 1
7 7
7 4
output
2
3
2
3
2
3
1
1
3
Note

In the first example, for a=[10,20,10]a=[10,20,10] the optimal subsequences are:

  • for k=1[20]
  • for k=2[10,20]
  • for k=3 [10,20,10]

 

 

题意:求含k个元素 ‘最优子序列’的第pos的元素值

先对题意理解,离线操作,

把序列从大到小排序(先按值大小 后按位置大小!)(卡了我n久)

把要询问求的最优子序列 按k排序

每次询问都是从上一个询问中插入元素

树状数组存的是每个元素的位置

二分位置 如果前缀和小于pos 那就要记录答案

#include<bits/stdc++.h>
#define sscc ios::sync_with_stdio(false)
#define lowbit(x)  x&(-x)
using namespace std;
const int maxn=2e5+10;
int n;
int a[maxn],sum[maxn],ans[maxn];
void add( int x,int val ){
	while( x<=n ) sum[x]+=val,x+=lowbit(x);
}
int query( int x ){
	int s=0;
	while( x>0 ) s+=sum[x],x-=lowbit(x);
	return s;
}
void solve(){
	cin>>n;
	for( int i=1;i<=n;i++ )	cin>>a[i];
	set<pair<int,int>> S;
	for( int i=1;i<=n;i++ ) S.insert(make_pair(-a[i],i));
	int m;
	scanf("%d",&m);
	vector<pair<pair<int,int>,int> >Q;
	for( int i=0;i<m;i++ )
	{
		int x,y;
		cin>>x>>y;
		Q.push_back( make_pair( make_pair(x,y),i ) );
	}
	sort(Q.begin(),Q.end());
//	for(int i=0;i<Q.size();i++){
//		cout<<Q[i].first.first<<" "<<Q[i].first.second<<" "<<Q[i].second<<endl;
//	}
	int now=0;
	for( int i=0;i<Q.size();i++ )
	{
		while( now<Q[i].first.first )
		{
			now++;
			pair<int,int> tmp=*S.begin();
			add(tmp.second,1);
			S.erase(tmp);
		}
		int pos=Q[i].first.second;
		int l=1,r=n;
		while( l<=r )
		{
			int  mid=(l+r)/2;
			if( query(mid)>=pos )
			{
				r=mid-1;
			}
			else l=mid+1;
		}
		ans[ Q[i].second ]=a[r+1];
	}
	for( int i=0;i<m;i++ ) cout<<ans[i]<<endl;
	
}
int main()
{
	cin.tie(0);
	cout.tie(0);
	solve();
	return 0;
}

  

cf 602 D 二分+树状数组

标签:cto   query   oss   preview   elements   OWIN   c++   and   back   

原文地址:https://www.cnblogs.com/lyj1/p/11991930.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!