首页 > 代码库 > 2017.3.4[hihocoder#1403]后缀数组一·重复旋律
2017.3.4[hihocoder#1403]后缀数组一·重复旋律
好久没发博了。
后缀数组板子题。具体实现就不解释了,hihocoder很良心。
http://hihocoder.com/problemset/problem/1403
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 20010 10 #define RG register 11 #define inf 0x3f3f3f3f 12 #define Inf 99999999999999999LL 13 using namespace std; 14 typedef long long LL; 15 int h,k,n,t,ans,a[N],b[N],q[N],sa[N],ssa[N],cnta[N],cntb[N],heit[N],Rank[N],music[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 (int i=1;i<=n;++i) ++cnta[music[i]]; 28 for (int i=1;i<=100;++i) cnta[i]+=cnta[i-1]; 29 for (int i=n;i;--i) sa[cnta[music[i]]--]=i; 30 Rank[sa[1]]=1; 31 for (int i=2;i<=n;++i){ 32 Rank[sa[i]]=Rank[sa[i-1]]; 33 if(music[sa[i]]!=music[sa[i-1]]) 34 ++Rank[sa[i]]; 35 } 36 for (int now=1;Rank[sa[n]]<n;now<<=1){ 37 memset(cnta,0,sizeof(cnta)); 38 memset(cntb,0,sizeof(cntb)); 39 for (int i=1;i<=n;++i){ 40 ++cnta[a[i]=Rank[i]]; //rank即为上一次排序好的第一关键字 41 ++cntb[b[i]=(i+now<=n)?Rank[i+now]:0];//rank[i+now]即为第二关键字 42 } 43 for (int i=1;i<=n;++i) cntb[i]+=cntb[i-1]; 44 for (int i=n;i;--i) ssa[cntb[b[i]]--]=i;//ssa即为按第二关键字排的“假”sa 45 for (int i=1;i<=n;++i) cnta[i]+=cnta[i-1]; 46 for (int i=n;i;--i) sa[cnta[a[ssa[i]]]--]=ssa[i];//相当于把i替换为ssa[i],从而达到双关键字排序的目的 47 Rank[sa[1]]=1; 48 for (int i=2;i<=n;++i){ 49 Rank[sa[i]]=Rank[sa[i-1]]; 50 if (a[sa[i]]!=a[sa[i-1]]||b[sa[i]]!=b[sa[i-1]]) ++Rank[sa[i]]; 51 } 52 } 53 for (int i=1,j=0;i<=n;++i){ 54 if(j) --j; 55 while (music[i+j]==music[sa[Rank[i]-1]+j]) ++j; 56 heit[Rank[i]]=j; 57 } 58 } 59 inline void work(){ 60 n=gi();k=gi(); 61 if(k==1){ 62 printf("%d\n",n); 63 return; 64 } 65 for (RG int i=1;i<=n;++i) 66 music[i]=gi(); 67 getsa(); 68 //for (RG int i=1;i<=n;++i) cout<<heit[i]<<‘ ‘; 69 //cout<<endl; 70 for (RG int i=1;i<=n;++i){ 71 while(h<t&&heit[i]<heit[q[t]]) --t; 72 q[++t]=i; 73 //cout<<q[h+1]<<‘ ‘<<q[t]<<endl; 74 while(q[h+1]<=q[t]-k+1) ++h; 75 if(h<t) ans=Max(ans,heit[q[h+1]]); 76 //cout<<ans<<endl; 77 } 78 printf("%d\n",ans); 79 } 80 int main(){ 81 work(); 82 return 0; 83 }
2017.3.4[hihocoder#1403]后缀数组一·重复旋律
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。