BZOJ3998: [TJOI2015]弦论

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3998

讲道理是一道很水的后缀自动机的题目,后缀自动机+第K大而已。

但像我这种蒟蒻,膜拜hzwer学长的博客膜了好久才改出来。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #define inf 1<<30
 5 #define maxn 500005
 6 using namespace std;
 7 int t,k,n;
 8 char s[maxn];
 9 struct sam{
10     int last,tot,par[maxn*2],val[maxn*2],sum[maxn*2],size[maxn*2],v[maxn],q[maxn*2],go[maxn*2][26];
11     sam(){last=++tot;}
12     int newnode(int x){val[++tot]=val[x]+1;return tot;}
13     void extend(int x){
14         int p=last,np=newnode(p); size[np]=1;
15         while(p&&go[p][x]==0) go[p][x]=np,p=par[p];
16         if(p==0) par[np]=1;
17         else{
18             int q=go[p][x];
19             if(val[q]==val[p]+1) par[np]=q;
20             else{
21                 int nq=newnode(p);
22                 memcpy(go[nq],go[q],sizeof(go[q]));
23                 par[nq]=par[q]; par[q]=par[np]=nq;
24                 while(p&&go[p][x]==q) go[p][x]=nq,p=par[p];
25             }
26         }
27         last=np;
28     }
29     void calc(){
30         for(int i=1;i<=tot;i++) v[val[i]]++;
31         for(int i=1;i<=n;i++) v[i]+=v[i-1];
32         for(int i=tot;i;i--) q[v[val[i]]--]=i;
33         for(int i=tot;i;i--){
34             if(t==1) size[par[q[i]]]+=size[q[i]];
35             else size[q[i]]=1;
36         }
37         size[1]=0;
38         for(int i=tot;i;i--){
39             sum[q[i]]=size[q[i]];
40             for(int j=0;j<26;j++) sum[q[i]]+=sum[go[q[i]][j]];
41         }
42     }
43     void dfs(int x,int y){
44         if(y<=size[x]) return;
45         y-=size[x];
46         for(int i=0;i<26;i++){
47             if(go[x][i]==0) continue;
48             if(y<=sum[go[x][i]]){
49                 putchar(i+'a'); dfs(go[x][i],y); return;
50             }
51             y-=sum[go[x][i]];
52         }
53     }
54 }sam;
55 int main(){
56     scanf("%s",s+1); n=strlen(s+1);
57     scanf("%d%d",&t,&k);
58     for(int i=1;i<=n;i++) sam.extend(s[i]-'a');
59     sam.calc();
60     if(k>sam.sum[1]) puts("-1");
61     else sam.dfs(1,k);
62     return 0;
63 }
View Code
原文地址:https://www.cnblogs.com/longshengblog/p/5551152.html