Description
\quad You are given a sequence of integers a = [ a 1 , a 2 . . . a n ] a=[a_{1},a_{2}...a_{n}] a=[a1,a2...an] of length n n n. Its subsequence is obtained by removing zero or more elements from the sequence a (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] a=[11,20,11,33,11,20,11]:
-
[
11
,
20
,
11
,
33
,
11
,
20
,
11
]
,
[
11
,
20
,
11
,
33
,
11
,
20
]
,
[
11
,
11
,
11
,
11
]
,
[
20
]
[11,20,11,33,11,20,11], [11,20,11,33,11,20], [11,11,11,11], [20]
[11,20,11,33,11,20,11],[11,20,11,33,11,20],[11,11,11,11],[20]
[ 33 , 20 ] [33,20] [33,20] are subsequences (these are just some of the long list); - [ 40 ] , [ 33 , 33 ] , [ 33 , 20 , 20 ] , [ 20 , 20 , 11 , 11 ] [40], [33,33], [33,20,20], [20,20,11,11] [40],[33,33],[33,20,20],[20,20,11,11] are not subsequences.
\quad Suppose that an additional non-negative integer k ( 1 ≤ k ≤ n ) k (1≤k≤n) k(1≤k≤n) is given, then the subsequence is called optimal if:
\quad
it has a length of
k
k
k and the sum of its elements is the maximum possible among all subsequences of length
k
k
k;
and among all subsequences of length
k
k
k that satisfy the previous item, it is lexicographically minimal.
Recall that the sequence
b
=
[
b
1
,
b
2
.
.
.
b
k
]
b=[b_{1},b_{2}...b_{k}]
b=[b1,b2...bk] is lexicographically smaller than the sequence
c
=
[
c
1
,
c
2
.
.
.
c
k
]
c=[c_{1},c_{2}...c_{k}]
c=[c1,c2...ck]] if the first element (from the left) in which they differ less in the sequence b than in c. Formally: there exists t (1≤t≤k) such that
b
1
=
c
1
,
b
2
=
c
2
.
.
.
.
b
t
−
1
=
c
t
−
1
b_{1}=c_{1},b_{2}=c_{2}....b_{t-1}=c_{t-1}
b1=c1,b2=c2....bt−1=ct−1 and at the same time
b
t
<
c
t
b_{t}<c_{t}
bt<ct. For example:
- [ 10 , 20 , 20 ] [10,20,20] [10,20,20] lexicographically less than [ 10 , 21 , 1 ] [10,21,1] [10,21,1],
- [ 7 , 99 , 99 ] [7,99,99] [7,99,99] is lexicographically less than [ 10 , 21 , 1 ] [10,21,1] [10,21,1],
- [ 10 , 21 , 0 ] [10,21,0] [10,21,0] is lexicographically less than [ 10 , 21 , 1 ] [10,21,1] [10,21,1].
\quad You are given a sequence of a = [ a 1 , a 2 . . . a n ] a=[a_{1},a_{2}...a_{n}] a=[a1,a2...an] and m requests, each consisting of two numbers k j k_{j} kj and p o s j pos_{j} posj ( 1 ≤ k ≤ n , 1 ≤ p o s j ≤ k j ) (1≤k≤n, 1≤pos_{j}≤k_{j}) (1≤k≤n,1≤posj≤kj). For each query, print the value that is in the index posj of the optimal subsequence of the given sequence a for k = k j k=k_{j} k=kj.
\quad For example, if n = 4 n=4 n=4, a = [ a 1 , a 2 . . . a n ] a=\left[a_{1},a_{2}...a_{n}\right] a=[a1,a2...an], k j = 2 k_{j}=2 kj=2, then the optimal subsequence is [ 20 , 30 ] [20,30] [20,30] — it is the minimum lexicographically among all subsequences of length 2 2 2 with the maximum total sum of items. Thus, the answer to the request k j = 2 k_{j}=2 kj=2, p o s j = 1 pos_{j}=1 posj=1 is the number 20 20 20, and the answer to the request k j = 2 k_{j}=2 kj=2, p o s j = 2 pos_{j}=2 posj=2 is the number 30 30 30.
Input
\quad The first line contains an integer n ( 1 ≤ n ≤ 2 ∗ 1 0 5 ) n\left(1≤n≤2*10^{5} \right) n(1≤n≤2∗105) — the length of the sequence a a a.
\quad The second line contains elements of the sequence a: integer numbers a 1 , a 2 . . . a n ( 1 ≤ a i ≤ 1 0 9 ) a_{1},a_{2}...a_{n}\left(1≤a_{i}≤10^{9} \right) a1,a2...an(1≤ai≤109)。
\quad The third line contains an integer m ( 1 ≤ m ≤ 2 ∗ 1 0 5 ) m\left(1≤m≤2*10^{5} \right) m(1≤m≤2∗105) — the number of requests.
\quad The following m lines contain pairs of integers k j k_{j} kj and p o s j pos_{j} posj ( 1 ≤ k ≤ n , 1 ≤ p o s j ≤ k j ) (1≤k≤n, 1≤pos_{j}≤k_{j}) (1≤k≤n,1≤posj≤kj) — the requests.
Output
\quad Print m integers r 1 , r 2 . . . r n ( 1 ≤ r i ≤ 1 0 9 ) r_{1},r_{2}...r_{n}\left(1≤r_{i}≤10^{9} \right) r1,r2...rn(1≤ri≤109) one per line: answers to the requests in the order they appear in the input. The value of r j r_{j} rj should be equal to the value contained in the position posj of the optimal subsequence for k = k j k=k_{j} k=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] the optimal subsequences are:
- for k=1: [20],
- for k=2: [10,20],
- for k=3: [10,20,10].
这道题的题意就是:给你一个序列,让你找一个长度为K的区间(可以不连续),这个区间的和最大,然后询问你这个区间第pos的数字是哪一个。
这个问题不就是区间第K大的问题吗,标准的主席树模板。
AC代码:
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define pd(n) printf("%d\n", n)
#define pc(n) printf("%c", n)
#define pdd(n,m) printf("%d %d", n, m)
#define pld(n) printf("%lld\n", n)
#define pldd(n,m) printf("%lld %lld\n", n, m)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sc(n) scanf("%c",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define ss(str) scanf("%s",str)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
#define mem(a,n) memset(a, n, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mod(x) ((x)%MOD)
#define gcd(a,b) __gcd(a,b)
#define lowbit(x) (x&-x)
typedef pair<int,int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const int maxn = 3e5 + 5;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
inline int read()
{
int ret = 0, sgn = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
sgn = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
ret = ret*10 + ch - '0';
ch = getchar();
}
return ret*sgn;
}
inline void Out(int a) //Êä³öÍâ¹Ò
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
int qpow(int m, int k, int mod)
{
int res = 1, t = m;
while (k)
{
if (k&1)
res = res * t % mod;
t = t * t % mod;
k >>= 1;
}
return res;
}
ll gcd(ll a,ll b)
{
return b==0?a : gcd(b,a%b);
}
ll lcm(ll a,ll b)
{
return a*b/gcd(a,b);
}
const int MAX_N=2e5+5;
int a[MAX_N];
int n,m;
struct node
{
int val,id;
} b[MAX_N];
bool cmp(node aa,node bb)
{
if(aa.val!=bb.val)
return aa.val>bb.val;
else
return aa.id<bb.id;
}
struct Node
{
int lc,rc,sum;
} tr[MAX_N*30];
int T[MAX_N],tot;
void build(int &k,int l,int r)
{
k=++tot;
tr[k].sum=0;
if(l==r)
return;
int mid=(l+r)>>1;
build(tr[k].lc,l,mid),build(tr[k].rc,mid+1,r);
}
void update(int &k,int l,int r,int pre,int x)
{
k=++tot;
tr[k]=tr[pre],tr[k].sum++;
if(l==r)
return;
int mid=(l+r)>>1;
if(x<=mid)
update(tr[k].lc,l,mid,tr[pre].lc,x);
else
update(tr[k].rc,mid+1,r,tr[pre].rc,x);
}
int query(int s,int e,int l,int r,int k)
{
if(l==r)
return l;
int mid=(l+r)>>1;
int lcleft=tr[tr[e].lc].sum-tr[tr[s].lc].sum;
if(k<=lcleft)
return query(tr[s].lc,tr[e].lc,l,mid,k);
else
return query(tr[s].rc,tr[e].rc,mid+1,r,k-lcleft);
}
int main()
{
sd(n);
rep(i,1,n)
{
sd(a[i]);
b[i].val=a[i],b[i].id=i;
}
sort(b+1,b+1+n,cmp);
build(T[0],1,n);
rep(i,1,n)
{
update(T[i],1,n,T[i-1],b[i].id);
}
sd(m);
int k,pos;
while(m--)
{
sd(k);
sd(pos);
printf("%d\n",a[query(T[0],T[k],1,n,pos)]);
}
return 0;
}
不过使用贪心+线段树也可以,这个思路是真的巧妙又学会一招。
不理解的可以看这张图,线段树维护的区间出现次数。
AC代码:
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <vector>
using namespace std;
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define pd(n) printf("%d\n", n)
#define pc(n) printf("%c", n)
#define pdd(n,m) printf("%d %d", n, m)
#define pld(n) printf("%lld\n", n)
#define pldd(n,m) printf("%lld %lld\n", n, m)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sc(n) scanf("%c",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define ss(str) scanf("%s",str)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
#define mem(a,n) memset(a, n, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mod(x) ((x)%MOD)
#define gcd(a,b) __gcd(a,b)
#define lowbit(x) (x&-x)
typedef pair<int,int> PII;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const int maxn = 3e5 + 5;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int inf = 0x3f3f3f3f;
inline int read()
{
int ret = 0, sgn = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
sgn = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
ret = ret*10 + ch - '0';
ch = getchar();
}
return ret*sgn;
}
inline void Out(int a) //Êä³öÍâ¹Ò
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
int qpow(int m, int k, int mod)
{
int res = 1, t = m;
while (k)
{
if (k&1)
res = res * t % mod;
t = t * t % mod;
k >>= 1;
}
return res;
}
ll gcd(ll a,ll b)
{
return b==0?a : gcd(b,a%b);
}
ll lcm(ll a,ll b)
{
return a*b/gcd(a,b);
}
const int N = 2e5 + 10;
int n, m, now;
int sum[N<<2];
struct node
{
int x,pos;
} a[N], b[N];
struct Node
{
int k,pos,id,ans;
} q[N];
void update(int l,int r,int rt,int pos)
{
if(pos==l&&l==r)
{
sum[rt]=1;
return ;
}
int mid=(l+r)>>1;
if(pos<=mid)
update(l,mid,rt<<1,pos);
else
update(mid+1,r,rt<<1|1,pos);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
int query(int l,int r,int rt,int k)
{
if(l==r)
return a[l].x;
int mid=(l+r)>>1;
if(sum[rt<<1]>=k)
return query(l,mid,rt<<1,k);
else
return query(mid+1,r,rt<<1|1,k-sum[rt<<1]);
}
bool cmp1(node &a,node &b)
{
return a.x==b.x?a.pos<b.pos:a.x>b.x;
}
bool cmp2(Node &a,Node &b)
{
return a.k<b.k;
}
bool cmp3(Node &a,Node &b)
{
return a.id<b.id;
}
int main()
{
sd(n);
now=0;
rep(i,1,n)
{
sd(a[i].x);
a[i].pos=i;
b[i]=a[i];
}
sort(b+1,b+n+1,cmp1);///把元素从大到小排序,位置从小到大
sd(m);
rep(i,1,m)
{
sdd(q[i].k,q[i].pos);
q[i].id=i;
}
sort(q+1,q+m+1,cmp2);///按照区间从小到大排序
rep(i,1,m)
{
while(now<q[i].k)
update(1,n,1,b[++now].pos);///从大到小把每个点更新
q[i].ans=query(1,n,1,q[i].pos);
}
sort(q+1,q+m+1,cmp3);///按照查询顺序排序
rep(i,1,m)
cout<<q[i].ans<<endl;
return 0;
}