hdu 3518 Boring counting

枚举子串的长度,然后判断是不是最远位置和最近的相隔满足大于等于子串的长度就好,,(然而本蒟蒻还是不会)

 1 #include<bits/stdc++.h>
 2 #define N 100005<<2
 3 #define LL long long
 4 #define inf 0x3f3f3f3f
 5 using namespace std;
 6 inline int ra()
 7 {
 8     int x=0,f=1; char ch=getchar();
 9     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
10     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
11     return x*f;
12 }
13 int n,k,p,q,ans;
14 int a[1005],v[1005];
15 int sa[2][1005],rk[2][1005],h[1005];
16 char ch[1005];
17 void cal_sa(int sa[N], int rk[N], int Sa[N], int Rk[N])
18 {
19     for (int i=1; i<=n; i++) v[rk[sa[i]]]=i;
20     for (int i=n; i>=1; i--)
21         if (sa[i]>k) Sa[v[rk[sa[i]-k]]--]=sa[i]-k;
22     for (int i=n-k+1; i<=n; i++)
23         Sa[v[rk[i]]--]=i;
24     for (int i=1; i<=n; i++) Rk[Sa[i]]=Rk[Sa[i-1]]+(rk[Sa[i]]!=rk[Sa[i-1]] || rk[Sa[i]+k]!=rk[Sa[i-1]+k]);
25 }
26 void work()
27 {
28     p=0,q=1;
29     for (int i=1; i<=n; i++) v[a[i]]++;
30     for (int i=1; i<=30; i++) v[i]+=v[i-1];
31     for (int i=1; i<=n; i++) sa[p][v[a[i]]--]=i;
32     for (int i=1; i<=n; i++) rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]);
33     for (k=1; k<n; k<<=1,q^=1,p^=1) cal_sa(sa[p],rk[p],sa[q],rk[q]);
34 }
35 void get_height()
36 {
37     k=0;
38     for (int i=1; i<=n; i++)
39     {
40         if (rk[p][i]==1) h[1]=0;
41         else{
42             int j=sa[p][rk[p][i]-1];
43             while (a[i+k]==a[j+k]) k++;
44             h[rk[p][i]]=k;
45             if (k>0) k--;
46         }
47     }
48 }
49 bool solve(int x)
50 {
51     bool flag=0;
52     int mx=sa[p][1],mn=sa[p][1];
53     for (int i=2; i<=n; i++)
54         if (h[i]<x)
55         {
56             if (mx-mn>=x) ans++,flag=1;
57             mx=mn=sa[p][i];
58         }
59         else
60         {
61             mx=max(mx,sa[p][i]);
62             mn=min(mn,sa[p][i]);
63         }
64     if (mx-mn>=x) ans++,flag=1;
65     return flag;
66 }
67 int main()
68 {
69     while (scanf("%s",ch+1))
70     {
71         if (ch[1]=='#') break;
72         memset(a,0,sizeof(a));
73         memset(v,0,sizeof(v));
74         memset(rk,0,sizeof(rk));
75         memset(sa,0,sizeof(sa));
76         n=strlen(ch+1);
77         for (int i=1; i<=n; i++) a[i]=ch[i]-'a'+1;
78         work(); get_height();
79         ans=0; 
80         for (int i=1; i<=(n+1)/2; i++)
81             if (!solve(i)) break;
82         cout<<ans<<endl;
83     }
84     return 0;
85 }
原文地址:https://www.cnblogs.com/ccd2333/p/6477184.html