SPOJ 7258 (后缀自动机)
转载:http://hzwer.com/4492.html
给一个长度不超过90000的串S,每次询问它的所有不同子串中,字典序第K小的,询问不超过500个。
搞出后缀自动机
dp处理出每个点往下走能够走出多少个串。
f[i]=sigma(f[ch[i][c])+1
这个可以按Max排序之后倒着推就好了。
询问的时候看一下走下去个数是否<=k,是的话就走下去,然后–k;否则就找下一条边
1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 29 29 30 30 31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 38 39 39 40 40 41 41 42 42 43 43 44 44 45 45 46 46 47 47 48 48 49 49 50 50 51 51 52 52 53 53 54 54 55 55 56 56 57 57 58 58 59 59 60 60 61 61 62 62 63 63 64 64 65 65 66 66 67 67 68 68 69 69 70 70 71 71 72 72 73 73 74 74 75 75 76 76 77 77 78 78 79 79 80 #include<iostream> 81 #include<cstdio> 82 #include<cstring> 83 #include<cstdlib> 84 #include<algorithm> 85 #include<cmath> 86 #define N 180005 87 #define inf 1000000000 88 using namespace std; 89 char ch[N]; 90 int Q,p,q,np,nq; 91 int cnt=1,last=1,n; 92 int fa[N],to[N][26],l[N],s[N]; 93 int f[N],v[N]; 94 void extend(int c) 95 { 96 p=last;np=last=++cnt;l[np]=++n; 97 for(;p&&!to[p][c];p=fa[p])to[p][c]=np; 98 if(!p)fa[np]=1; 99 else 100 { 101 int q=to[p][c]; 102 if(l[p]+1==l[q])fa[np]=q; 103 else 104 { 105 nq=++cnt;l[nq]=l[p]+1; 106 memcpy(to[nq],to[q],sizeof(to[q])); 107 fa[nq]=fa[q]; 108 fa[q]=fa[np]=nq; 109 for(;to[p][c]==q;p=fa[p])to[p][c]=nq; 110 } 111 } 112 } 113 void build() 114 { 115 scanf("%s",ch); 116 for(char *c=ch;*c;c++)extend(*c-'a'); 117 } 118 void pre() 119 { 120 for(int i=1;i<=cnt;i++)v[l[i]]++; 121 for(int i=1;i<=n;i++)v[i]+=v[i-1]; 122 for(int i=1;i<=cnt;i++)s[v[l[i]]--]=i; 123 for(int i=cnt;i;i--) 124 { 125 f[s[i]]=1; 126 for(int j=0;j<26;j++) 127 f[s[i]]+=f[to[s[i]][j]]; 128 } 129 } 130 void query() 131 { 132 p=1;int x; 133 scanf("%d",&x); 134 while(x) 135 { 136 for(int i=0;i<26;i++) 137 if(to[p][i]) 138 { 139 if(f[to[p][i]]>=x) 140 { 141 putchar('a'+i); 142 p=to[p][i]; 143 --x;break; 144 } 145 else x-=f[to[p][i]]; 146 } 147 } 148 printf("\n"); 149 } 150 int main() 151 { 152 build(); 153 pre(); 154 scanf("%d",&Q); 155 while(Q--) 156 query(); 157 return 0; 158 }