重复旋律1
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#define RG register
#define IL inline
#define pi acos(-1.0)
#define ll long long
using namespace std;
int gi() {
char ch=getchar(); int x=0;
while(ch<'0' || ch>'9') ch=getchar();
while(ch>='0' && ch<='9') {x=10*x+ch-'0';ch=getchar();}
return x;
}
const int maxn = 20010;
int n,ck,inf=1<<30,ans;
int t1[maxn],t2[maxn],c[maxn],s[maxn],sa[maxn];
int ra[maxn],he[maxn];
int q[maxn];
void get_sa(int m) {
int i,*x=t1,*y=t2;
for(i=0; i<m; i++) c[i]=0;
for(i=0; i<n; i++) c[x[i]=s[i]]++;
for(i=1; i<m; i++) c[i]+=c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[i]]]=i;
for(int k=1; k<=n; k<<=1) {
int p=0;
for(i=n-k; i<n; i++) y[p++]=i;
for(i=0; i<n; i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(i=0; i<m; i++) c[i]=0;
for(i=0; i<n; i++) c[x[y[i]]]++;
for(i=1; i<m; i++) c[i]+=c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[y[i]]]]=y[i];//这时的sa是以第二关键字的排名的排列的
swap(x,y);//把x数组赋给y数组
p=1,x[sa[0]]=0;
for(i=1; i<n; i++)
x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
if(p>=n) break;
m=p;
}
}
void get_he() {
int i,j,k=0;
for(i=0; i<=n; i++) ra[sa[i]]=i;
for(i=0; i<n; i++) {
if(k) k--;
j=sa[ra[i]-1];//rank[n]=0,不会出现负下标
while(s[i+k] == s[j+k]) k++;
he[ra[i]]=k;
}
}
int cal() {//单调队列O(n)维护最小值(单增队列)
int hd=1,ta=0,res=0;
for(int i=1; i<ck; i++) {
while(hd<=ta && he[i]<he[q[ta]]) ta--;
q[++ta]=i;
}//先将队列扩展到[1,k-1]
for(int i=ck; i<=n; i++) {//每次逐次往后移动一个1格,求[i-k+1,i]的最值,即为队头
while(hd<=ta && he[i]<he[q[ta]]) ta--;
q[++ta]=i;
while(hd<=ta && q[hd]<=i-ck+1) hd++;
res=max(res,he[q[hd]]);
}
return res;
}
/*
要点:
1'先扩展到k-1
2'维持单调
3'区间求最值
*/
int main() {
n=gi(),ck=gi();
for(int i=0; i<n; i++) s[i]=gi();
n++;
get_sa(100);
n--;
get_he();
int ans=cal();
printf("%d", ans);
return 0;
}
重复旋律2
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#define RG register
#define IL inline
#define pi acos(-1.0)
#define ll long long
using namespace std;
int gi() {
char ch=getchar(); int x=0;
while(ch<'0' || ch>'9') ch=getchar();
while(ch>='0' && ch<='9') {x=10*x+ch-'0';ch=getchar();}
return x;
}
const int maxn = 100010;
int n,m=1000,ans;
int s[maxn],t1[maxn],t2[maxn],c[maxn];
int sa[maxn],he[maxn],ra[maxn];
void get_sa() {
int i,*x=t1,*y=t2;
for(i=0; i<m; i++) c[i]=0;
for(i=0; i<n; i++) c[x[i]=s[i]]++;
for(i=1; i<m; i++) c[i]+=c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[i]]]=i;
for(int k=1; k<=n; k<<=1) {
int p=0;
for(i=n-k; i<n; i++) y[p++]=i;
for(i=0; i<n; i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(i=0; i<m; i++) c[i]=0;
for(i=0; i<n; i++) c[x[y[i]]]++;
for(i=1; i<m; i++) c[i]+=c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y);
p=1,x[sa[0]]=0;
for(i=1; i<n; i++)
x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
if(p>=n) break;
m=p;
}
}
void get_he() {
int i,j,k=0;
for(i=1; i<=n; i++) ra[sa[i]]=i;
for(i=0; i<n; i++) {
if(k) k--;
j=sa[ra[i]-1];//排名在i前面的字符下标j
while(s[i+k]==s[j+k]) k++;
he[ra[i]]=k;
}
}
bool check(int k) {
int minsa=1<<30,maxsa=0;
for(int i=1; i<=n; i++) {
if(he[i]<k) {
maxsa=sa[i];
minsa=sa[i];
}
else {
maxsa=max(sa[i],maxsa);
minsa=min(sa[i],minsa);
if(maxsa-minsa>=k) return true;
}
}
return false;
}
int main() {
n=gi();
for(int i=0; i<n; i++) s[i]=gi();
m++,n++,get_sa(),n--;
get_he();
int l=0,r=n,mid;
while(l<=r) {
mid=(l+r)>>1;
if(check(mid)) ans=max(ans,mid),l=mid+1;
else r=mid-1;
}
printf("%d", ans);
return 0;
}
重复旋律3
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#define RG register
#define IL inline
#define pi acos(-1.0)
#define ll long long
using namespace std;
int gi() {
char ch=getchar(); int x=0;
while(ch<'0' || ch>'9') ch=getchar();
while(ch>='0' && ch<='9') {x=10*x+ch-'0';ch=getchar();}
return x;
}
const int maxn = 100100;
int n,m=101,ls1,ls2;
char s1[maxn],s2[maxn];
int s[maxn*2],c[maxn*3],t1[maxn*2],t2[maxn*2];
int sa[maxn*2],ra[maxn*2],he[maxn*2];
void get_sa() {
int i,*x=t1,*y=t2;
for(i=0; i<m; i++) c[i]=0;
for(i=0; i<n; i++) c[x[i]=s[i]]++;
for(i=1; i<m; i++) c[i]+=c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[i]]]=i;
for(int k=1; k<=n; k<<=1) {
int p=0;
for(i=n-k; i<n; i++) y[p++]=i;
for(i=0; i<n; i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(i=0; i<m; i++) c[i]=0;
for(i=0; i<n; i++) c[x[y[i]]]++;
for(i=1; i<=m; i++) c[i]+=c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y);
p=1,x[sa[0]]=0;
for(i=1; i<n; i++)
x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
if(p>=n) break;
m=p;
}
}
void get_he() {
int i,j,k=0;
for(i=0; i<=n; i++) ra[sa[i]]=i;
for(i=0; i<n; i++) {
if(k) k--;
j=sa[ra[i]-1];
while(s[j+k]==s[i+k]) k++;
he[ra[i]]=k;
}
}
int solve() {
int ans=0;
for(int i=1; i<=n; i++) {
if((sa[i]<ls1 && sa[i-1]>ls1) || (sa[i]>ls1 && sa[i-1]<ls1)) {
ans=max(ans,he[i]);
}
}
return ans;
}
int main() {
scanf("%s%s", s1,s2);
ls1=strlen(s1),ls2=strlen(s2);
for(int i=0; i<ls1; i++) s[i]=s1[i]-'a'+1;
s[ls1]=100;
for(int i=1; i<=ls2; i++)
s[i+ls1]=s2[i-1]-'a'+1;
n=ls1+ls2+1;
n++;
get_sa();
n--;
get_he();
printf("%d", solve());
return 0;
}
重复旋律4
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#define RG register
#define IL inline
#define pi acos(-1.0)
#define ll long long
using namespace std;
int gi() {
char ch=getchar(); int x=0;
while(ch<'0' || ch>'9') ch=getchar();
while(ch>='0' && ch<='9') {x=10*x+ch-'0';ch=getchar();}
return x;
}
const int maxn = 100010;
int n,m=27,ans;
char s1[maxn];
int s[maxn],c[maxn],t1[maxn],t2[maxn];
int sa[maxn],ra[maxn],he[maxn];
int dp[maxn][22];
void get_sa() {
int i,*x=t1,*y=t2;
for(i=0; i<m; i++) c[i]=0;
for(i=0; i<n; i++) c[x[i]=s[i]]++;
for(i=1; i<m; i++) c[i]+=c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[i]]]=i;
for(int k=1; k<=n; k<<=1) {
int p=0;
for(i=n-k; i<n; i++) y[p++]=i;
for(i=0; i<n; i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(i=0; i<m; i++) c[i]=0;
for(i=0; i<n; i++) c[x[y[i]]]++;
for(i=1; i<m; i++) c[i]+=c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y);
p=1,x[sa[0]]=0;
for(i=1; i<n; i++)
x[sa[i]]=y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
if(p>=n) break;
m=p;
}
}
void get_he() {
int i,j,k=0;
for(i=1; i<=n; i++) ra[sa[i]]=i;
for(i=0; i<n; i++) {
if(k) k--;
j=sa[ra[i]-1];
while(s[j+k]==s[i+k]) k++;
he[ra[i]]=k;
}
}
void prepare() {
memset(dp,127/3,sizeof(dp));
for(int i=1; i<=n; i++)
dp[i][0]=he[i];
for(int j=1; j<=20; j++)
for(int i=1; i+(1<<j-1)<=n; i++)
dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);
}
int lcp(int l, int r) {
l=ra[l],r=ra[r];//注意取排名
if(l>r) swap(l,r);
l++;
int len=r-l+1;
int k=(int)(log(len)/log(2));
return min(dp[l][k],dp[r-(1<<k)+1][k]);
}
int solve() {//纯抄题解
for(int L=1; L<=n; L++) {
for(int i=1; i+L<=n; i+=L) {
int R=lcp(i,i+L);
ans=max(ans,R/L+1);
if(i>=L-R%L) ans=max(ans,lcp(i-L+R%L,i+R%L)/L+1);
}
}
return ans;
}
int main() {
scanf("%s", s1);
n=strlen(s1);
for(int i=0; i<n; i++) s[i]=s1[i]-'a'+1;
n++,get_sa(),n--;
get_he();
prepare();
printf("%d\n", solve());
return 0;
}