/**************************************************************
Problem: 3238
User: Clare
Language: C++
Result: Accepted
Time:2912 ms
Memory:132624 kb
****************************************************************/
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
#define N 500010
char S[N];
int Ws[N];
long long Ans;
struct Edge{
int next,to;
}edge[N*2];
int head[N*2],Tot;
struct SAM{
SAM *fa,*son[26];
int size,val;
void S_clear(){
fa=0;val=0;size=0;
memset(son,0,sizeof(son));
}
}*last,*tot,*root,State[N*2],*pos[N*2];
void Addedge(int u,int v)
{
Tot++;
edge[Tot].next=head[u];
edge[Tot].to=v;
head[u]=Tot;
}
void Init()
{
tot=State;root=last=tot++;
root->S_clear();
}
void Insert(int w)
{
SAM *p=last,*np=tot++;np->S_clear();
np->val=p->val+1;np->size=1;
while(p&&!p->son[w])
p->son[w]=np,p=p->fa;
if(!p)
np->fa=root;
else
{
SAM *q=p->son[w];
if(q->val==p->val+1)
np->fa=q;
else
{
SAM *nq=tot++;nq->S_clear();
nq->val=p->val+1;
memcpy(nq->son,q->son,sizeof(q->son));
nq->fa=q->fa;q->fa=np->fa=nq;
while(p&&p->son[w]==q)
p->son[w]=nq,p=p->fa;
}
}
last=np;
}
void DFS(SAM *x,SAM *f)
{
int xx=(int)(x-State);
for(int i=head[xx];i;i=edge[i].next)
{
int vv=edge[i].to;
SAM *v=State+vv;
DFS(v,x);
x->size+=v->size;
}
Ans-=(long long)x->size*(x->size-1)*(x->val-f->val);
}
int main()
{
scanf("%s",S);
Init();
int len=(int)strlen(S);
for(int i=len-1;i>=0;i--)
Insert(S[i]-'a');
for(SAM *p=State;p!=tot;p++)
{
if(!p->fa)
continue;
int now=(int)(p-State),f=(int)(p->fa-State);
Addedge(f,now);
}
Ans=(long long)len*(len-1)*(len+1)/2;
for(int i=head[0];i;i=edge[i].next)
{
SAM *v=State+edge[i].to;
DFS(v,root);
}
cout<<Ans<<endl;
return 0;
}
bzoj 3238 差异
最新推荐文章于 2024-09-30 09:00:00 发布