题解:P10716 【MX-X1-T4】「KDOI-05」简单的字符串问题
刻画一下合法的
首先
然后
考虑从第二个限制入手,你发现
不妨记
注意到假若串
处理
#include<bits/stdc++.h>
using namespace std;
//#define int long long
//#define lowbit(x) (x&(-x))
//#define bp push_back
//#define sz size
//#define cl clear
const int maxn = 2e5+114;
int n,q;
char c[maxn];
int nxt[maxn];
vector<int> E[maxn];
set<int> S[maxn];
vector<int> dp[maxn];
int fa[maxn][20];
int dep[maxn];
void dfs(int u){
S[u].insert(u);
for(int v:E[u]){
dep[v]=dep[u]+1;
fa[v][0]=u;
for(int i=1;i<19;i++) fa[v][i]=fa[fa[v][i-1]][i-1];
dfs(v);
if(S[v].size()>S[u].size()) swap(S[u],S[v]);
for(int x:S[v]) S[u].insert(x);
}
if(u==0) return ;
dp[u].push_back(0);
dp[u].push_back(u);
int st=u+u;
while(S[u].lower_bound(st)!=S[u].end()){
dp[u].push_back((*S[u].lower_bound(st)));
st=dp[u].back()+u;
}
}
int answer[maxn];
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>c[i];
for(int i=2;i<=n;i++){
int z=nxt[i-1];
while(c[z+1]!=c[i]&&z!=0) z=nxt[z];
if(c[z+1]==c[i]) z++;
nxt[i]=z;
}
for(int i=1;i<=n;i++) E[nxt[i]].push_back(i);
dfs(0);
cin>>q;
for(int i=1;i<=q;i++){
int l,k;
cin>>l>>k;
if(k==1) cout<<1<<'\n';
else{
int u=l;
for(int i=19;i>=0;i--){
if(fa[u][i]!=0&&((dp[fa[u][i]].size()-1<k)||(dp[fa[u][i]][k]>l))) u=fa[u][i];
}
cout<<dep[fa[u][0]]<<'\n';
}
}
return 0;
}
/*
10
aabaacaaaa
1
10 5
*/