[Ahoi2013]差异
Posted XD-TEST
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Ahoi2013]差异相关的知识,希望对你有一定的参考价值。
后缀数组+单调栈
代码
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 const int N = 501000; 6 7 const int MAXN = N; 8 9 struct SuffixArray{ 10 int wa[MAXN]; 11 int wb[MAXN]; 12 int wv[MAXN]; 13 int ws[MAXN]; 14 15 int sa[MAXN]; 16 int rank[MAXN]; 17 int height[MAXN]; 18 int r[MAXN]; 19 int n; 20 int m; 21 22 void input(int *val, int len, int Max){ 23 for (int i = 0;i < len;i++) 24 r[i] = val[i]; 25 r[len] = 0; 26 n = len; 27 m = Max; 28 calSa(); 29 calHeight(); 30 } 31 32 int cmp(int *r, int a, int b, int l){ 33 return (r[a] == r[b] && r[a + l] == r[b + l]); 34 } 35 36 void calSa(){ 37 int i, j, p, *x = wa, *y = wb, *t; 38 for (i = 0;i < m;i++) ws[i] = 0; 39 for (i = 0;i < n + 1;i++) ws[x[i] = r[i]]++; 40 for (i = 1;i < m;i++) ws[i] += ws[i - 1]; 41 for (i = n;i >= 0;i--) sa[--ws[x[i]]] = i; 42 for (j = 1, p = 1;p < n + 1;j *= 2, m = p){ 43 for (p = 0, i = n - j + 1;i < n + 1;i++) y[p++] = i; 44 for (i = 0;i < n + 1;i++) if (sa[i] >= j) y[p++] = sa[i] - j; 45 for (i = 0;i < n + 1;i++) wv[i] = x[y[i]]; 46 for (i = 0;i < m;i++) ws[i] = 0; 47 for (i = 0;i < n + 1;i++) ws[wv[i]]++; 48 for (i = 1;i < m;i++) ws[i] += ws[i - 1]; 49 for (i = n;i >= 0;i--) sa[--ws[wv[i]]] = y[i]; 50 for (t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n + 1;i++) 51 x[sa[i]] = cmp(y, sa[i - 1], sa[i], j) ? p - 1 : p++; 52 } 53 } 54 55 void calHeight(){ 56 int i, j, k = 0; 57 for (i = 1;i <= n;i++) rank[sa[i]] = i; 58 for (i = 0;i < n;height[rank[i++]] = k) 59 for (k?k--:0, j = sa[rank[i]- 1];r[i + k] == r[j + k];k++); 60 } 61 62 int Log[MAXN]; 63 int best[20][MAXN]; 64 void initRMQ() { 65 Log[0] = -1; 66 for(int i = 1;i <= MAXN;i++){ 67 Log[i]=(i & (i - 1))?Log[i - 1] : Log[i - 1] + 1 ; 68 } 69 for(int i = 1; i <= n ; i ++) best[0][i] = height[i]; 70 for(int i = 1; i <= Log[n] ; i ++) { 71 int limit = n - (1<<i) + 1; 72 for(int j = 1; j <= limit ; j ++) { 73 best[i][j] = (best[i-1][j] > best[i-1][j+(1<<i>>1)]) ? best[i-1][j+(1<<i>>1)] : best[i-1][j]; 74 } 75 } 76 } 77 int lcp(int a,int b) { 78 a = rank[a]; b = rank[b]; 79 if(a > b){ 80 int t = a; 81 a = b; 82 b = t; 83 } 84 a ++; 85 int t = Log[b - a + 1]; 86 return (best[t][a] > best[t][b - (1<<t) + 1])? best[t][b - (1<<t) + 1] : best[t][a]; 87 } 88 }SA; 89 int a[N],i,len,top,stack[N]; 90 long long ans,sum; 91 char s[N]; 92 int main() 93 { 94 scanf("%s",&s); 95 len=strlen(s); 96 for (i=1;i<=len;i++) 97 { 98 ans=ans+(long long)i*(len-1); 99 a[i-1]=s[i-1]; 100 } 101 SA.input(a,len,200); 102 for (i=1;i<=len;i++) 103 { 104 while (SA.height[i]<SA.height[stack[top]]) 105 { 106 sum=sum-(long long)(stack[top]-stack[top-1])*SA.height[stack[top]]; 107 top--; 108 } 109 top++;stack[top]=i; 110 sum=sum+(long long)(stack[top]-stack[top-1])*SA.height[stack[top]]; 111 ans=ans-2*sum; 112 } 113 printf("%lld\n",ans); 114 } 115 //3 1 4 2 5 0
以上是关于[Ahoi2013]差异的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 3238: [Ahoi2013]差异 -- 后缀数组