字符串小结
Posted HITLJR
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符串小结相关的知识,希望对你有一定的参考价值。
kmp就直接略过吧
AC自动机,后缀数组,回文树,……(后续待学)
AC自动机
模板
1 #include <bits/stdc++.h> 2 const long long mod = 1e9+7; 3 const double ex = 1e-10; 4 const int maxn = 5000005; 5 const int maxm = 30; 6 #define inf 0x3f3f3f3f 7 using namespace std; 8 int ans = 0; 9 int a[100]; 10 int T[1123456]; 11 char tc[100]; 12 char Tc[1123456]; 13 struct Trie{ 14 int ch[maxn][maxm]; 15 int last[maxn]; 16 int val[maxn]; 17 int f[maxn]; 18 int vis[maxn]; 19 int sz; 20 Trie() { 21 sz = 1; 22 for (int i = 0; i<maxm ; i++) 23 ch[0][i] = 0; 24 } 25 void init(){ 26 for (int i = 0; i<=1; i++){ 27 for (int j = 0 ; j < maxm ; j++){ 28 ch[i][j] = 0; 29 } 30 val[i] = 0; 31 f[i] = 0; 32 last[i] = 0; 33 } 34 sz = 1; 35 } 36 void insert(int l,int v){ 37 int u = 0; 38 for (int i = 0; i<l; i++){ 39 int c = a[i]; 40 if (!ch[u][c]){ 41 memset(ch[sz],0,sizeof(ch[sz])); 42 val[sz] = 0; 43 ch[u][c] = sz++; 44 } 45 u = ch[u][c]; 46 } 47 //val[u] = v; 48 val[u]++; 49 vis[u] = 0; 50 } 51 void getFail(){ 52 queue <int> q; 53 for (int c = 0;c<maxm;c++){ 54 int u = ch[0][c]; 55 if (u){ 56 f[u] = 0; 57 q.push(u); 58 last[u] = 0; 59 } 60 } 61 while (!q.empty()){ 62 int r = q.front();q.pop(); 63 for (int c = 0;c<maxm;c++){ 64 int u = ch[r][c]; 65 //if (!u){ 66 // ch[r][c] = ch[f[r]][c];continue; 67 //} 68 if (!u) continue; 69 q.push(u); 70 int v = f[r]; 71 while (v && !ch[v][c]) v = f[v]; 72 f[u] = ch[v][c]; 73 last[u] = val[f[u]] ? f[u] : last[f[u]]; 74 } 75 } 76 } 77 void find(int n){ 78 int j = 0; 79 for (int i = 0 ; i < n ;i++){ 80 int c = T[i]; 81 while (j && !ch[j][c]) j = f[j]; 82 j = ch[j][c]; 83 if (val[j] && !vis[j]) print(j); 84 else if (last[j] && !vis[last[j]]) print(last[j]); 85 } 86 } 87 void print(int j){ 88 if (j&&!vis[j]){ 89 ans+=val[j]; 90 vis[j] = 1; 91 print(last[j]); 92 } 93 } 94 95 }Tri; 96 97 int main() 98 { 99 int t; 100 scanf("%d",&t); 101 while (t--){ 102 int N; 103 scanf("%d",&N); 104 Tri.init(); 105 for (int i = 1; i <=N; i++){ 106 scanf("%s",tc); 107 int l = strlen(tc); 108 //assert(l>=51); 109 for (int j = 0 ; j < l ; j++){ 110 a[j] = tc[j]-\'a\'; 111 } 112 Tri.insert(l,i); 113 } 114 Tri.getFail(); 115 scanf("%s",Tc); 116 int l = strlen(Tc); 117 for (int j = 0 ; j < l ; j++){ 118 T[j] = Tc[j]-\'a\'; 119 } 120 ans = 0; 121 Tri.find(l); 122 printf("%d\\n",ans); 123 } 124 return 0; 125 }
例题
后缀数组
模板
1 const int maxn = 800005; 2 int sa[maxn],t[maxn],t2[maxn],c[maxn],n; 3 int bb[maxn]; 4 int s[maxn]; 5 void build_sa(int m){ 6 int *x = t, *y = t2; 7 for (int i = 0 ; i< m ;i++) c[i] = 0; 8 for (int i = 0 ; i < n ; i++) c[x[i] = s[i]]++; 9 for (int i = 1; i<m ;i++) c[i] += c[i-1]; 10 for (int i = n - 1 ; i >= 0 ; i--) sa[--c[x[i]]] = i; 11 for (int k = 1; k <= n ;k<<=1){ 12 int p = 0; 13 for (int i = n-k; i < n; i++) y[p++] = i; 14 for (int i = 0 ; i < n ; i++) if (sa[i] >= k ) y[p++] = sa[i] - k; 15 for (int i = 0 ; i < m ; i++) c[i] = 0; 16 for (int i = 0 ; i < n ; i++) c[x[y[i]]]++; 17 for (int i = 1 ; i < m ;i++) c[i] += c[i-1]; 18 for (int i = n - 1 ; i >= 0 ; i--) sa[--c[x[y[i]]]] = y[i]; 19 swap(x,y); 20 p = 1;x[sa[0]] = 0; 21 for (int i = 1; i < n ; i++) 22 x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1] + k] == y[sa[i] + k]?p-1:p++; 23 if (p >= n)break; 24 m = p; 25 26 } 27 } 28 int ran[maxn],height[maxn]; 29 //from 1 to n-1; 30 //sa[0] = n-1; 31 //ran[n-1] = 0; the last is 0; 32 // height 代表 和 前面的 33 void getHeight(){ 34 int k = 0; 35 for (int i = 0 ; i<n ;i++) ran[sa[i]] = i; 36 for (int i = 0; i<n ;i++){ 37 if (k) k--; 38 int j = sa[ran[i]-1]; 39 while (s[i+k] == s[j+k]) {k++;} 40 height[ran[i]] = k; 41 } 42 } 43 void print(){ 44 for (int i = 0 ; i<=10; i++) 45 cout << sa[i] <<" "; 46 cout << endl; 47 for (int i = 0 ; i<=10; i++) 48 cout << ran[i] <<" "; 49 cout << endl; 50 for (int i = 0 ; i<=10; i++) 51 cout << height[i] <<" "; 52 cout << endl; 53 54 }
例题:http://codeforces.com/gym/101470/attachments B题
1 #include <bits/stdc++.h> 2 const long long mod = 1e9+7; 3 const double ex = 1e-10; 4 #define inf 0x3f3f3f3f 5 using namespace std; 6 const int maxn = 200005; 7 int s[maxn]; 8 char ss[maxn]; 9 int sa[maxn],t[maxn],t2[maxn],c[maxn],n; 10 int N,K; 11 void build_sa(int m){ 12 int *x = t, *y = t2; 13 for (int i = 0; i < m ; i++) c[i] = 0; 14 for (int i = 0; i < n ; i++) c[x[i] = s[i]]++; 15 for (int i = 1; i < m ; i++) c[i] += c[i-1]; 16 for (int i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i; 17 for (int k = 1 ; k <= n ; k <<= 1){ 18 int p = 0; 19 for (int i = n-k ; i < n ; i++) y[p++] = i; 20 for (int i = 0; i < n ; i++) if (sa[i] >= k ) y[p++] = sa[i] - k; 21 for (int i = 0 ; i < m ; i++) c[i] = 0; 22 for (int i = 0 ; i < n ; i++) c[x[y[i]]]++; 23 for (int i = 1 ; i < m ; i++) c[i] += c[i-1]; 24 for (int i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i]; 25 swap(x,y); 26 p = 1;x[sa[0]] = 0; 27 for (int i = 1 ; i < n ; i++) 28 x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i] + k]?p-1:p++; 29 if (p >= n) break; 30 m = p; 31 } 32 } 33 int ran[maxn],height[maxn]; 34 void getrank(){ 35 for (int i = 0 ; i < n ; i++) ran[sa[i]] = i; 36 } 37 bool check2(int pos,int id){ 38 int cnt = 0; 39 //cout << pos << " "<<id <<" !" << endl; 40 for (int i = 1; i<=K ;i++){ 41 //cout << pos <<" " << ran[pos] << endl; 42 if (ran[pos]<=id){ 43 pos+=(N+K-1)/K; 44 if (pos >= N) pos -= N; 45 ++cnt; 46 } 47 else { 48 if (N%K==0) return false; 49 pos+=N/K; 50 if (pos >= N) pos -= N; 51 } 52 } 53 //cout << endl; 54 return ((cnt) >= (N % K)); 55 } 56 bool check(int id){ 57 for (int i = 0; i<(N+K-1)/K ; i++){ 58 if (check2(i,id)){ 59 return true; 60 } 61 } 62 return false; 63 } 64 void print(){ 65 for (int i = 0; i<=30; i++) 66 cout << ran[i] <<" "; 67 cout << endl; 68 for (int i = 0; i<=30; i++) 69 cout << sa[i] <<" "; 70 cout << endl; 71 for (int i = 0; i<=30; i++) 72 cout << height[i] <<" "; 73 cout << endl; 74 75 } 76 int main() 77 { 78 freopen("B.in","r",stdin); 79 scanf("%d%d",&N,&K); 80 scanf(" %s",ss); 81 for (int i = 0; i<N; i++){ 82 s[i] = ss[i] - \'0\'; 83 } 84 for (int i = 0 ; i < N; i++){ 85 s[i+N] = s[i]; 86 } 87 n = 2*N+1; 88 s[2*N] = 0; 89 build_sa(10); 90 getrank(); 91 92 //print(); 93 int l = 0; 94 int r = n-1; 95 int ans = 0; 96 int cnt = 0; 97 while (l <= r){ 98 int mid = (l+r)/2; 99 if (check(mid)){ 100 ans = mid; 101 r = mid - 1; 102 } 103 else{ 104 l = mid + 1; 105 } 106 } 107 for (int j = 0 ; j < (N+K-1) / K ; j++){ 108 cout << s[sa[ans]+j]; 109 } 110 cout << endl; 111 return 0; 112 }
回文树
http://blog.csdn.net/u013368721/article/details/42100363
杭电大佬学习笔记
模板
1 const int MAXN = 200022; 2 const int N = 26; 3 char A[200022],B[200022]; 4 struct Palindromic_Tree{ 5 int next[MAXN][N]; 6 int fail[MAXN]; 7 int cnt[MAXN]; 8 int num[MAXN]; 9 int len[MAXN]; 10 int S[MAXN]; 11 int last; 12 int n; 13 int p; 14 int newnode(int l){ 15 for (int i = 0; i < N; i++) next[p][i] = 0; 16 cnt[p] = 0; 17 num[p] = 0; 18 len[p] = l; 19 return p++; 20 } 21 void init(){ 22 p = 0; 23 newnode(0); 24 newnode(-1); 25 last = 0; 26 n = 0; 27 S[n] = -1; 28 fail[0] = 1; 29 } 30 int get_fail(int x){ 31 while (S[n - len[x] - 1] != S[n]) x=fail[x]; 32 return x; 33 } 34 void add(int c){ 35 c -= \'a\'; 36 S[++n] = c; 37 int cur = get_fail(last); 38 if (!next[cur][c]){ 片段(Java) | 机试题+算法思路+考点+代码解析 2023