题解
类似离散化后就是主席树模板题。
#include<bits/stdc++.h>
using namespace std;
string s[100010];
int t[100010],di[100010];
int tong[100010],tong2[100010];
int id[100010];
int v[4000010];
int l[4000010],r[4000010];
int root[100010];
int tot=0;
int build(int a,int b){
int x=++tot;
if(a==b) return x;
int mid=(a+b)>>1;
l[x]=build(a,mid);
r[x]=build(mid+1,b);
return x;
}
int update(int x,int a,int b,int z,int c){
int y=++tot; v[y]=v[x]+c;
if(a==b) return y;
int mid=(a+b)>>1;
if(mid>=z) l[y]=update(l[x],a,mid,z,c),r[y]=r[x];
if(mid<z) l[y]=l[x],r[y]=update(r[x],mid+1,b,z,c);
return y;
}
int query(int x,int y,int k,int a,int b){
if(a==b) return a;
int mid=(a+b)>>1;
if(v[l[x]]-v[l[y]]>=k) return query(l[x],l[y],k,a,mid);
else return query(r[x],r[y],k-(v[l[x]]-v[l[y]]),mid+1,b);
}
int main(){
ios::sync_with_stdio(false);
int n,q;
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>s[i];
int len=s[i].size();
for(int j=0;j<len;j++) t[i]=t[i]*10+s[i][j]-48;tong[t[i]]=i;
}
sort(s+1,s+n+1);
for(int i=1;i<=n;i++){
int len=s[i].size();
for(int j=0;j<len;j++) id[i]=id[i]*10+s[i][j]-48;
di[tong[id[i]]]=i;
}
for(int i=1;i<=n;i++) tong2[di[i]]=i;
root[n+1]=build(1,n);
for(int i=n;i;i--) root[i]=update(root[i+1],1,n,di[i],1);
while(q--){
int a,b,k;
cin>>a>>b>>k;
if(k>(b-a+1)){
cout<<"-1"<<endl;
continue;
}
int ans=query(root[a],root[b+1],k,1,n);
cout<<t[tong2[ans]]<<endl;
}
return 0;
}
本文介绍了一道关于主席树的数据结构题目,通过离散化处理,实现字符串的快速查找与更新操作。具体包括主席树的建立、更新及查询等核心算法,并通过实际代码示例详细解释了每一步的具体实现。
193

被折叠的 条评论
为什么被折叠?



