好久没写博客了。北京区域赛前先把模板往博客上储存一下,以免以后忘记了。

  分块的话在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\n",ans);
92     }
93     return 0;
94 }
后缀数组