标签:nbsp ref -- present acm osi mem letter position
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=3518
题目:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3187 Accepted Submission(s): 1320
1 #include <cstdlib>
2 #include <cstring>
3 #include <cstdio>
4 #include <algorithm>
5
6 const int N = 200005;
7 int sa[N],s[N],wa[N], wb[N], ws[N], wv[N];
8 int rank[N], height[N];
9
10 bool cmp(int r[], int a, int b, int l)
11 {
12 return r[a] == r[b] && r[a+l] == r[b+l];
13 }
14 void calheight(int r[], int sa[], int n)
15 {
16 int i, j, k = 0;
17 for (i = 1; i <= n; ++i) rank[sa[i]] = i;
18 for (i = 0; i < n; height[rank[i++]] = k)
19 for (k?k--:0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k++);
20 }
21 void da(int r[], int sa[], int n, int m)
22 {
23 int i, j, p, *x = wa, *y = wb;
24 for (i = 0; i < m; ++i) ws[i] = 0;
25 for (i = 0; i < n; ++i) ws[x[i]=r[i]]++;
26 for (i = 1; i < m; ++i) ws[i] += ws[i-1];
27 for (i = n-1; i >= 0; --i) sa[--ws[x[i]]] = i;
28 for (j = 1, p = 1; p < n; j *= 2, m = p)
29 {
30 for (p = 0, i = n - j; i < n; ++i) y[p++] = i;
31 for (i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
32 for (i = 0; i < n; ++i) wv[i] = x[y[i]];
33 for (i = 0; i < m; ++i) ws[i] = 0;
34 for (i = 0; i < n; ++i) ws[wv[i]]++;
35 for (i = 1; i < m; ++i) ws[i] += ws[i-1];
36 for (i = n-1; i >= 0; --i) sa[--ws[wv[i]]] = y[i];
37 for (std::swap(x, y), p = 1, x[sa[0]] = 0, i = 1; i < n; ++i)
38 x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1 : p++;
39 }
40 calheight(r,sa,n-1);
41 }
42
43 int check(int lc,int x)
44 {
45 int mi=sa[1],mx=sa[1],ans=0;
46 for(int i=2;i<=lc;i++)
47 {
48 if(height[i]<x)
49 {
50 if(mx-mi>=x)
51 ans++;
52 mx=mi=sa[i];
53 }
54 else
55 {
56 mx=std::max(mx,sa[i]);
57 mi=std::min(mi,sa[i]);
58 }
59 }
60 if(mx-mi>=x)ans++;
61 return ans;
62 }
63 char ss[N];
64 int main()
65 {
66 while(scanf("%s",ss)==1)
67 {
68 if(ss[0]==‘#‘)break;
69 int la=strlen(ss),n=0,ans=0;
70 for(int i=0;i<la;i++)
71 s[n++]=ss[i]-‘a‘+1;
72 s[n]=0;
73 da(s,sa,n+1,30);
74 for(int i=1;i<=n/2;i++)
75 ans+=check(n,i);
76 printf("%d\n",ans);
77 }
78 return 0;
79 }
标签:nbsp ref -- present acm osi mem letter position
原文地址:http://www.cnblogs.com/weeping/p/6649002.html