好久没写博客了。北京区域赛前先把模板往博客上储存一下,以免以后忘记了。
分块的话在vjudge上搜索:备战区域赛-数据结构分块-キリト。
后缀数组的话搜索kuangbin的后缀数组即可。
1 int n,m; 2 //num分块的个数 3 //belong[i]表示i属于哪一块 4 //block表示块的大小 5 //l[i]表示i这块的左端点位置 6 //r[i]表示右端点位置 7 int block,num,l[N],r[N],belong[N]; 8 int build() 9 { 10 block = (int)sqrt(1.0*n); 11 num = n / block;if(n%block) num++; 12 for(int i=1;i<=num;i++) l[i] = (i-1)*block+1, r[i] = i*block; 13 r[num] = n; 14 for(int i=1;i<=n;i++) belong[i] = (i-1)/block + 1; 15 }
1 /*下面的代码用来解决两个比较长的字符串的最长公共子串的长度:中间插个未出现的字符,再连接后进行构造即可。*/ 2 #include <stdio.h> 3 #include <algorithm> 4 #include <string.h> 5 using namespace std; 6 const int N = 100000*2 + 100; 7 typedef long long ll; 8 9 /** 10 * sa[i]:表示排在第i位的后缀的起始下标 11 * rank[i]:表示后缀suffix(i)排在第几 12 * height[i]:sa[i-1] 与 sa[i]的LCP(最长公共前缀)值 13 * 14 * */ 15 /* 16 如果整数的话模板改成int. 17 加一个数a[n] = 0 。 这样他的排名是第一个。 18 construct(a,n+1); 19 20 字符串的话。 21 len = strlen(str); 22 construct(s,strlen(s)+1); 23 排名第0的是个空字符串。 24 25 height[i]:sa[i-1] 与 sa[i]的LCP(最长公共前缀)值 26 所以height[1] = 0; 27 rank[len] = 0; 28 sa[0] = len; 29 */ 30 int sa[N],rnk[N],height[N]; 31 void construct(const char *s,int n,int m = 256) { 32 static int t1[N],t2[N],c[N]; 33 int *x = t1,*y = t2; 34 int i,j,k,p,l; 35 for (i = 0; i < m; ++ i) c[i] = 0; 36 for (i = 0; i < n; ++ i) c[x[i] = s[i]] ++; 37 for (i = 1; i < m; ++ i) c[i] += c[i - 1]; 38 for (i = n - 1; i >= 0; -- i) sa[--c[x[i]]] = i; 39 for (k = 1; k <= n; k <<= 1) { 40 p = 0; 41 for (i = n - k; i < n; ++ i) y[p++] = i; 42 for (i = 0; i < n; ++ i) if (sa[i] >= k) y[p++] = sa[i] - k; 43 for (i = 0; i < m; ++ i) c[i] = 0; 44 for (i = 0; i < n; ++ i) c[x[y[i]]] ++; 45 for (i = 1; i < m; ++ i) c[i] += c[i - 1]; 46 for (i = n - 1; i >= 0; -- i) sa[--c[x[y[i]]]] = y[i]; 47 std::swap(x,y); 48 p = 1; x[sa[0]] = 0; 49 for (i = 1; i < n; ++ i) 50 x[sa[i]] = y[sa[i - 1]] == y[sa[i]] 51 && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1: p ++; 52 if (p >= n) break; 53 m = p; 54 } 55 for (i = 0; i < n; ++ i) rnk[sa[i]] = i; 56 for (i = 0,l = 0; i < n; ++ i) { 57 if (rnk[i]) { 58 j = sa[rnk[i] - 1]; 59 while (s[i + l] == s[j + l]) l++; 60 height[rnk[i]] = l; 61 if (l) l--; 62 } 63 } 64 } 65 66 int T; 67 char s[N],s2[N]; 68 69 int main() 70 { 71 while(scanf("%s",s+1)==1) 72 { 73 scanf("%s",s2+1); 74 int len = strlen(s+1); 75 int temp = len; 76 s[len+1] = '$'; 77 for(int i=len+2,now=1;s2[now];i++,now++) 78 { 79 s[i] = s2[now]; 80 if(s2[now+1] == 0) {s[i+1] = 0;len=i;} 81 } 82 83 construct(s,len+1); 84 int ans = 0; 85 for(int i=2;i<=len;i++) 86 { 87 int a = min(sa[i-1],sa[i]); 88 int b = max(sa[i-1],sa[i]); 89 if(a<=temp && b>temp+1) ans = max(ans,height[i]); 90 } 91 printf("%d ",ans); 92 } 93 return 0; 94 }