标签:== pen open gif count 后缀 oid src mic
kmp就直接略过吧
AC自动机,后缀数组,回文树,……(后续待学)
AC自动机
模板
例题
后缀数组
模板
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]){ 39 int now = newnode(len[cur] + 2); 40 fail[now] = next[get_fail(fail[cur])][c]; 41 next[cur][c] = now; 42 num[now] = num[fail[now]] + 1; 43 } 44 last = next[cur][c]; 45 cnt[last]++; 46 } 47 void count(){ 48 for (int i = p - 1; i>=0; --i) cnt[fail[i]] += cnt[i]; 49 } 50 }; 51 Palindromic_Tree a,b;
例题
2014 西安 G题
就是在建好的回文树上进行DFS计数。
深刻理解了count的作用。
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 = 200022; 7 const int N = 26; 8 char A[200022],B[200022]; 9 struct Palindromic_Tree{ 10 int next[MAXN][N]; 11 int fail[MAXN]; 12 int cnt[MAXN]; 13 int num[MAXN]; 14 int len[MAXN]; 15 int S[MAXN]; 16 int last; 17 int n; 18 int p; 19 int newnode(int l){ 20 for (int i = 0; i < N; i++) next[p][i] = 0; 21 cnt[p] = 0; 22 num[p] = 0; 23 len[p] = l; 24 return p++; 25 } 26 void init(){ 27 p = 0; 28 newnode(0); 29 newnode(-1); 30 last = 0; 31 n = 0; 32 S[n] = -1; 33 fail[0] = 1; 34 } 35 int get_fail(int x){ 36 while (S[n - len[x] - 1] != S[n]) x=fail[x]; 37 return x; 38 } 39 void add(int c){ 40 c -= ‘a‘; 41 S[++n] = c; 42 int cur = get_fail(last); 43 if (!next[cur][c]){ 44 int now = newnode(len[cur] + 2); 45 fail[now] = next[get_fail(fail[cur])][c]; 46 next[cur][c] = now; 47 num[now] = num[fail[now]] + 1; 48 } 49 last = next[cur][c]; 50 cnt[last]++; 51 } 52 void count(){ 53 for (int i = p - 1; i>=0; --i) cnt[fail[i]] += cnt[i]; 54 } 55 }; 56 Palindromic_Tree a,b; 57 long long dfs(int x,int y){ 58 long long tans = 0; 59 for (int i = 0 ; i< 26 ; i++){ 60 if (a.next[x][i]&&b.next[y][i]){ 61 tans += 1LL*a.cnt[a.next[x][i]]*b.cnt[b.next[y][i]] + dfs(a.next[x][i],b.next[y][i]); 62 } 63 } 64 return tans; 65 } 66 int main() 67 { 68 int T; 69 scanf("%d",&T); 70 for (int cas = 1; cas <= T; cas++){ 71 scanf(" %s",A); 72 scanf(" %s",B); 73 a.init(); 74 b.init(); 75 int la = strlen(A); 76 int lb = strlen(B); 77 for (int i = 0 ; i < la ; i++){ 78 a.add(A[i]); 79 } 80 for (int i = 0 ; i < lb ; i++){ 81 b.add(B[i]); 82 } 83 a.count(); 84 b.count(); 85 long long ans = 0; 86 ans = dfs(0,0) + dfs(1,1); 87 printf("Case #%d: %lld\n",cas,ans); 88 } 89 }
标签:== pen open gif count 后缀 oid src mic
原文地址:http://www.cnblogs.com/HITLJR/p/7687872.html