2017.3.4[hihocoder#1407]后缀数组二·重复旋律2

重复旋律大礼包

http://hihocoder.com/problemset/problem/1407

 1 #include<cmath>
 2 #include<queue>
 3 #include<cstdio>
 4 #include<vector>
 5 #include<cstdlib>
 6 #include<cstring>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define N 100010
10 #define RG register
11 #define inf 0x3f3f3f3f
12 #define Inf 99999999999999999LL
13 using namespace std;
14 typedef long long LL;
15 int l=1,n,r,ans,a[N],b[N],sa[N],num[N],ssa[N],cnta[N],cntb[N],heit[N],order[N];
16 inline int Abs(RG const int &a){return a>0?a:-a;}
17 inline int Max(RG const int &a,RG const int &b){return a>b?a:b;}
18 inline int Min(RG const int &a,RG const int &b){return a>b?b:a;}
19 inline int gi(){
20     RG int x=0;RG bool flag=0;RG char c=getchar();
21     while((c<'0'||c>'9')&&c!='-') c=getchar();
22     if(c=='-') c=getchar(),flag=1;
23     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
24     return flag?-x:x;
25 }
26 inline void getsa(){
27     for (RG int i=1;i<=n;++i)    ++cnta[num[i]];
28     for (RG int i=1;i<=1000;++i) cnta[i]+=cnta[i-1];
29     for (RG int i=n;i;--i)       sa[cnta[num[i]]--]=i;
30     order[sa[1]]=1;
31     //cout<<"sdmo"<<endl;
32     if(n>1){
33     for (RG int i=2;i<=n;++i){
34         order[sa[i]]=order[sa[i-1]];
35         if(num[sa[i]]!=num[sa[i-1]]) ++order[sa[i]];
36     }
37     //cout<<"cdsamoc"<<endl;
38         for (RG int now=1;order[sa[n]]<n;now<<=1){
39         memset(cnta,0,sizeof(cnta));
40         memset(cntb,0,sizeof(cntb));
41         for (RG int i=1;i<=n;++i){
42             ++cnta[a[i]=order[i]];
43             ++cntb[b[i]=(i+now<=n)?order[i+now]:0];
44         }
45         for (RG int i=1;i<=n;++i) cntb[i]+=cntb[i-1];
46         for (RG int i=n;i;--i)    ssa[cntb[b[i]]--]=i;
47         for (RG int i=1;i<=n;++i) cnta[i]+=cnta[i-1];
48         for (RG int i=n;i;--i)    sa[cnta[a[ssa[i]]]--]=ssa[i];
49         order[sa[1]]=1;
50         for (RG int i=2;i<=n;++i){
51         order[sa[i]]=order[sa[i-1]];
52         if(a[sa[i]]!=a[sa[i-1]]||b[sa[i]]!=b[sa[i-1]]) ++order[sa[i]];
53         }
54     }
55     //cout<<"dsji"<<endl;
56     }
57     for (RG int i=1,j=0;i<=n;++i){
58     if(j) --j;
59     while(num[i+j]==num[sa[order[i]-1]+j]) ++j;
60     heit[order[i]]=j;
61     }
62 }
63 inline bool check(RG int mid){
64     RG int maxn,minn=inf;
65     for (RG int i=1;i<=n;++i)
66     if(heit[i]<mid)
67         maxn=minn=sa[i];
68     else{
69         maxn=Max(maxn,sa[i]);
70         minn=Min(minn,sa[i]);
71         if(maxn-minn>=mid) return 1;
72     }
73     return 0;
74 }
75 inline void work(){
76     n=gi();r=n;
77     for (RG int i=1;i<=n;++i) num[i]=gi();
78     //cout<<"cesj"<<endl;
79     getsa();
80     //cout<<"feanfila"<<endl;
81     while(l<=r){
82     RG int mid=(l+r)>>1;
83     if(check(mid)) ans=mid,l=mid+1;
84     else           r=mid-1;
85     }
86     printf("%d
",ans);
87 }
88 int main(){
89     work();
90     return 0;
91 }
View Code
原文地址:https://www.cnblogs.com/Super-Nick/p/6502676.html