您的位置:首页 > 其它

BZOJ 3676: [Apio2014]回文串

2016-04-03 12:48 387 查看
昨天BC打得我好伤心QAQ

T1模数为毛是(1e8)+7,坑了我一个小时

T2 T4果断不会

T3看出来是回文树了

发现好像没学过哎

只好现学(抄)了一下

然后由于不是很懂,于是写挂了

今天学了一下顺便复习了马拉车

感觉还是很简单的

(但是依然不会证复杂度,感觉有点慢啊)

于是把这题水了一下

大概是回文树+拓扑排序吧

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=300000+5;
typedef long long ll;
struct Node{
int len,suflink;
int ch[26];
ll sum;
void clear(){
memset(ch,0,sizeof(ch));
len=suflink=0;sum=0;
}
}tr
;
int suf,num;
void init(){
suf=num=2;
tr[1].clear();tr[1].len=-1;tr[1].suflink=1;
tr[2].clear();tr[2].len=0;tr[2].suflink=1;
}
char s
;
bool AddLetter(int pos){
int cur=suf,curlen=0;
int c=s[pos]-'a';
while(true){
curlen=tr[cur].len;
if(pos-1-curlen>=0&&s[pos-1-curlen]==s[pos])break;
cur=tr[cur].suflink;
}
if(tr[cur].ch[c]){
suf=tr[cur].ch[c];
tr[suf].sum++;
return false;
}
suf=++num;
tr[suf].clear();
tr[suf].len=tr[cur].len+2;
tr[suf].sum=1;
tr[cur].ch[c]=suf;
if(tr[suf].len==1){
tr[suf].suflink=2;
return true;
}
while(true){
cur=tr[cur].suflink;
curlen=tr[cur].len;
if(pos-1-curlen>=0&&s[pos-1-curlen]==s[pos]){
tr[suf].suflink=tr[cur].ch[c];
return true;
}
}
}
int deg
;
ll toposort(){
for(int i=1;i<=num;i++)
deg[tr[i].suflink]++;
queue<int>q;
for(int i=1;i<=num;i++)
if(!deg[i])q.push(i);
while(!q.empty()){
int u=q.front();q.pop();
int v=tr[u].suflink;
tr[v].sum+=tr[u].sum;
deg[v]--;
if(!deg[v])q.push(v);
}
ll ans=0;
for(int i=1;i<=num;i++)
ans=max(ans,tr[i].len*tr[i].sum);
return ans;
}
int main(){
//freopen("a.in","r",stdin);
scanf("%s",s);
int n=strlen(s);
init();
for(int i=0;i<n;i++)
AddLetter(i);
printf("%lld\n",toposort());
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: