Uva 12206 Stammering Aliens
阿新 • • 發佈:2018-02-21
region load png highlight return string mat reg tdi
題目描述
輸入輸出格式
輸入格式:
輸出格式:
輸入輸出樣例
輸入樣例#1:3 baaaababababbababbab 11 baaaababababbababbab 3 cccccc 0輸出樣例#1:
5 12 none 4 2
這個題後綴數組或者二分+hash好像都能做,,,但是我只是練一下後綴自動機而已hhhhh
這個題我們求的顯然就是right集合大小>=m的max{}的最大值,至於求最右開端的話,我們只需要記錄一下
right集合的最右點是哪個就行了,然後用這個減去答案長度就是最右開端。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #define ll long long #define maxn 170005 using namespace std; int l[maxn],siz[maxn],n,r[maxn]; int cnt=1,pre=1,m,ans,pos; int ch[maxn][26],f[maxn]; int a[maxn],c[maxn]; char s[maxn]; inline void init(){ memset(ch,0,sizeof(ch)); memset(f,0,sizeof(f)); memset(c,0,sizeof(c)); memset(siz,0,sizeof(siz)); memset(r,0,sizeof(r)); cnt=pre=1,l[1]=siz[1]=0; ans=pos=0; } inline void ins(int x){ int p=pre,np=++cnt; pre=np,l[np]=l[p]+1; siz[np]=1,r[np]=l[np]; for(;p&&!ch[p][x];p=f[p]) ch[p][x]=np; if(!p) f[np]=1; else{ int q=ch[p][x]; if(l[q]==l[p]+1) f[np]=q; else{ int nq=++cnt; l[nq]=l[p]+1; memcpy(ch[nq],ch[q],sizeof(ch[q])); f[nq]=f[q]; f[q]=f[np]=nq; for(;ch[p][x]==q;p=f[p]) ch[p][x]=nq; } } } inline void build(){ for(int i=0;i<n;i++) ins(s[i]-‘a‘); for(int i=1;i<=cnt;i++) c[l[i]]++; for(int i=n;i>=0;i--) c[i]+=c[i+1]; for(int i=1;i<=cnt;i++) a[c[l[i]]--]=i; } inline void solve(){ for(int i=1;i<=cnt;i++){ int now=a[i]; siz[f[now]]+=siz[now]; r[f[now]]=max(r[f[now]],r[now]); if(l[now]&&siz[now]>=m){ if(l[now]>ans) ans=l[now],pos=r[now]; else if(ans==l[now]&&r[now]>pos) pos=r[now]; } } } int main(){ while(scanf("%d",&m)==1&&m){ scanf("%s",s),n=strlen(s); init(); build(); solve(); if(ans) printf("%d %d\n",ans,pos-ans); else puts("none"); } return 0; }
Uva 12206 Stammering Aliens