【后缀数组】洛谷 P2852 Milk Patterns

题意:求可重叠连续出现次数至少为k的最长子串长度

裸后缀数组

二分长度len后

扫一遍height[],rmq求最小值,满足最小值大于等于len即return 1

复杂度O(nlogn)

 1 #include <bits/stdc++.h>
 2 #define For(i,a,b) for(int i=a;i<=b;++i)
 3 #define Dec(i,b,a) for(int i=b;i>=a;--i)
 4 #define file() freopen("c://users/asus/desktop/v.txt","r",stdin);
 5 #define IO ios::sync_with_stdio(0),cin.tie(0)
 6 #define inf 0x3f3f3f3f
 7 using namespace std;
 8 typedef long long ll;
 9 
10 const int N = 40010;
11 int n,m,K;
12 int sa[N],rk[N],a[N],b[N],ht[N],d[N][20],c[N],t[N],t2[N];
13 void make_sa()
14 {
15     n++; m++;
16     int *x=t,*y=t2,i,j,k;
17     for(i=0;i<m;++i) c[i]=0;
18     for(i=0;i<n;++i) ++c[x[i]=a[i]];
19     for(i=1;i<m;++i) c[i]+=c[i-1];
20     for(i=n-1;~i;--i) sa[--c[x[i]]]=i;
21     for(k=1;k<=n;k<<=1)
22     {
23         int p=0;
24         for(i=n-k;i<n;++i) y[p++]=i;
25         for(i=0;i<n;++i) if(k<=sa[i]) y[p++]=sa[i]-k;
26         for(i=0;i<m;++i) c[i]=0;
27         for(i=0;i<n;++i) ++c[x[y[i]]];
28         for(i=1;i<m;++i) c[i]+=c[i-1];
29         for(i=n-1;~i;--i) sa[--c[x[y[i]]]]=y[i];
30         swap(x,y); p=1; x[sa[0]]=0;
31         for(i=1;i<n;++i)
32             x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++;
33         if(p>=n) break;
34         m=p;
35     }
36     n--;
37     for(i=0;i<=n;++i) rk[sa[i]]=i;
38     for(i=0,k=0;i<n;++i)
39     {
40         if(k) --k;
41         j=sa[rk[i]-1];
42         while(a[i+k]==a[j+k]) k++;
43         ht[rk[i]]=k;
44     }
45 }
46 void make_st()
47 {
48     for(int i=1;i<=n;++i) d[i][0]=ht[i];
49     for(int j=1;(1<<j)<=n;++j)
50         for(int i=1;i+(1<<j)-1<=n;++i)
51             d[i][j]=min(d[i][j-1],d[i+(1<<j-1)][j-1]);
52 }
53 int rmq(int l,int r)
54 {
55     int k=log2(r-l+1);
56     return min(d[l][k],d[r-(1<<k)+1][k]);
57 }
58 bool check(int k)
59 {
60     for(int l=1,r=K-1;r<=n;++l,++r)
61         if(rmq(l,r)>=k) return 1;
62     return 0;
63 }
64 int main()
65 {
66     IO;
67     // file();
68     cin>>n>>K; int i;
69     for(i=0;i<n;++i) cin>>a[i],b[i]=a[i];
70     sort(b,b+n);
71     m=unique(b,b+n)-b;
72     for(i=0;i<n;++i) a[i]=lower_bound(b,b+m,a[i])-b+1;
73     make_sa();
74     make_st();
75     int l=1,r=n,mid;
76     while(l<=r)
77     {
78         mid=l+r>>1;
79         if(check(mid)) l=mid+1;
80         else r=mid-1;
81     }
82     cout<<l-1<<"\n";
83     return 0;
84 }

猜你喜欢

转载自www.cnblogs.com/uuuxxllj/p/11071176.html