P10995 【MX-J3-T2】Substring 题解
题目传送门
题目大意
给出一个长度为
总共有
思路讲解
设序列
在对
-
如果
l_1=l_2 说明x 为y 的前缀,因为x 的长度不超过y 的长度,所以当r_1 \ne r_2 时,x 的字典序小于y 的字典序,否则x 和y 的字典序相等。 -
如果
l_1 \ne l_2 ,则可以直接比较a_{l_1} 和a_{l_2} ,a_{l_1} 小则x 的字典序小,否则y 的字典序小。因为1 \sim n 只会在a 中出现一次,不会出现a_i=a_j(1 \le i < j \le n) 的情况。
根据上面的结论,我们可以将
设
对于每一次询问,由于
算法复杂度为
代码实现
#include <bits/stdc++.h>
using namespace std;
int n,q,a[300005],id[300005];
long long p[300005];
int main(){
//p[i]=开头为i,长度为1的排名
//id[i]为b[i]
cin>>n>>q;
for(int i=1;i<=n;i++){
cin>>a[i];
id[a[i]]=i;
}
long long sum=1;
for(int i=1;i<=n;i++){
p[i]=sum;
sum+=n-id[i]+1;
}
while(q--){
long long t;
cin>>t;
int l=1,r=n;
while(l<r){
int mid=(l+r+1)/2;
if(p[mid]<=t)
l=mid;
else
r=mid-1;
}
cout<<id[l]<<' '<<id[l]+t-p[l]<<'\n';
}
return 0;
}
完结撒花!