文章目录
R e s u l t Result Result
H y p e r l i n k Hyperlink Hyperlink
https://ac.nowcoder.com/acm/contest/7613/C
D e s c r i p t i o n Description Description
给定一个长度为 n n n的序列, m m m个询问,求静态区间字典序第 k k k大
数据范围: n , m ≤ 1 0 5 n,m\leq 10^5 n,m≤105
S o l u t i o n Solution Solution
转换成字符串之后排序,得到一个新的 r a n k rank rank,记为 c c c,对 c c c建立主席树,在建立映射数组 a a a,表示这个位置上的数原来对应的数
时间复杂度: O ( n log n ) O(n\log n) O(nlogn)
C o d e Code Code
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100010
#define LL long long
using namespace std;int T[N],sum[N<<5],L[N<<5],R[N<<5],n,q,a[N],b[10],len,c[N],cnt,x,y,z;
struct node{int id,a;string s;}p[N];
inline bool cmp(node x,node y){return x.s<y.s;}
inline LL read()
{
LL d=1,f=0;char c;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline int build(int l,int r)
{
int rt=++cnt,mid=l+r>>1;
if(l==r) {L[rt]=R[rt]=rt;return rt;}
L[rt]=build(l,mid);
R[rt]=build(mid+1,r);
return rt;
}
inline int updata(int pre,int l,int r,int x)
{
int rt=++cnt,mid=l+r>>1;
L[rt]=L[pre];R[rt]=R[pre];sum[rt]=sum[pre]+1;
if(l^r)
{
if(x<=mid) L[rt]=updata(L[pre],l,mid,x);
else R[rt]=updata(R[pre],mid+1,r,x);
}
return rt;
}
inline int query(int p,int q,int l,int r,int k)
{
if(l>=r) return l;
int x=sum[L[q]]-sum[L[p]],mid=l+r>>1;
if(x>=k) return query(L[p],L[q],l,mid,k);
else return query(R[p],R[q],mid+1,r,k-x);
}
signed main()
{
n=read();q=read();
for(int i=1;i<=n;i++)
{
x=p[i].a=read();p[i].id=i;len=0;
while(x) b[len++]=x%10,x/=10;
reverse(b,b+len);
for(int j=0;j<len;j++) p[i].s+=b[j]+48;
}
sort(p+1,p+1+n,cmp);
for(int i=1;i<=n;i++) c[p[i].id]=i,a[i]=p[i].a;
T[0]=build(1,n);
for(int i=1;i<=n;i++) T[i]=updata(T[i-1],1,n,c[i]);
while(q--)
{
x=read();y=read();z=read();
if(z>y-x+1) {puts("-1");continue;}
int t=query(T[x-1],T[y],1,n,z);
printf("%d\n",a[t]);
}
}