日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SPOJ 7258 (后缀自动机)

發布時間:2023/12/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 }

?

轉載于:https://www.cnblogs.com/agenthtb/p/7696201.html

總結

以上是生活随笔為你收集整理的SPOJ 7258 (后缀自动机)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。