您的位置:首页 > 其它

不是回文串

2016-04-12 18:55 260 查看

题目大意

把APIO2014的回文串条件改为无限制。

该题还要限定出现次数大于1。

求答案。

SAM裸题

建出SAM。

不过要额外维护一个mxstep代表从根节点走到自动机上一个结点的最长路。

然后统计size。

注意的是据说这题不用桶排会超时。

接下来扫描每一个结点,如果其size大于1,就让mxstep[i]*size[i]与ans比较。

#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
const int maxn=2500000+10;
int pre[maxn],step[maxn],mxstep[maxn],size[maxn],g[maxn][27],id[maxn];
char s[maxn],ch;
int i,j,k,l,t,n,m,tot,top,last,ans;
char get(){
char ch=getchar();
while (ch<'a'||ch>'z') ch=getchar();
return ch;
}
void insert(char ch){
int np=++tot;
size[np]=1;
mxstep[np]=step[np]=step[last]+1;
int p=last;
while (p&&g[p][ch-'a']==0){
g[p][ch-'a']=np;
mxstep[np]=max(mxstep[np],mxstep[p]+1);
p=pre[p];
}
if (!p) pre[np]=1;
else{
int q=g[p][ch-'a'];
if (step[q]==step[p]+1) pre[np]=q;
else{
int nq=++tot;
mxstep[nq]=step[nq]=step[p]+1;
pre[nq]=pre[q];
pre[q]=nq;
int i;
fo(i,0,26) g[nq][i]=g[q][i];
pre[np]=nq;
while (p&&g[p][ch-'a']==q){
g[p][ch-'a']=nq;
mxstep[nq]=max(mxstep[nq],mxstep[p]+1);
p=pre[p];
}
}
}
last=np;
}
bool cmp(int a,int b){
if (step[a]<step[b]) return 1;
else if (step[a]==step[b]&&a<b) return 1;
else return 0;
}
int main(){
//freopen("word4.in","r",stdin);freopen("3127.out","w",stdout);
while (1){
ch=getchar();
if (ch<'a'||ch>'z') break;
s[++n]=ch;
}
//n=strlen(s+1);
last=tot=1;
fo(i,1,n) insert(s[i]);
fo(i,1,tot) id[i]=i;
sort(id+1,id+tot+1,cmp);
fd(i,tot,1)
if (pre[id[i]]>1) size[pre[id[i]]]+=size[id[i]];
ans=0;
fo(i,1,tot)
if (size[i]>1) ans=max(ans,mxstep[i]*size[i]);
printf("%d\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: