题目描述
题解
并没有注意到相邻串字母不同,x=1想到用辅助数组加速跳next
首先显然离线,对每一段末尾求next,next的定义修改为匹配到的位置一定所在串的末尾
第一段长度大于等于,其他段长度刚好等于,把每一段当作特殊字符来做kmp,在找的时候算答案,答案是若干等差数列之和
由于kmp时间均摊,所以直接跳会被卡,因此如果长度大于一半的话就判断然后跳到周期等差数列的开头,时间是log的
总时间为O(nlog|S|)
code
实际上暴力跳也可以
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(a,b) (a<b?a:b)
#define mod 998244353
#define ll long long
#define file
using namespace std;
int a[100011][2],A[100011][2],ls[100011],d[100011][2],id[100011],nx[100011],n,i,j,k,l,len,tot,tp;
ll ans,Len[100011],Ans[100001];
vector<int> b[100011];
char ch;
void New(int x,int y,int s1,int s2) {++len;a[len][0]=y;a[len][1]=ls[x];ls[x]=len;A[len][0]=s1,A[len][1]=s2;}
void dfs(int t,ll ans)
{
ll ANS=ans;
int i;
j=b[t].size();
fo(i,0,j-1)
Ans[b[t][i]]=ans;
for (i=ls[t]; i; i=a[i][1])
{
++tot;d[tot][0]=A[i][0],d[tot][1]=A[i][1];Len[tot]=Len[tot-1]+A[i][1];
if (tot==1) nx[tot]=0,ans=(1ll*A[i][1]*(A[i][1]-1)/2)%mod;
else
{
nx[tot]=nx[tot-1];l=0;
while (nx[tot] && !(d[nx[tot]+1][0]==d[tot][0] && d[nx[tot]+1][1]==d[tot][1]))
{
if (d[nx[tot]+1][0]==d[tot][0] && d[nx[tot]+1][1]>l)
{
k=min(d[nx[tot]+1][1],A[i][1]);
ans=(ans+Len[nx[tot]]*(k-l)%mod+(1ll*(l+1+k)*(k-l)/2)%mod)%mod;
l=k;
}
if (Len[nx[nx[tot]]]>Len[nx[tot]]/2)
{
if (!(d[nx[nx[tot]]+1][0]==d[tot][0] && (d[nx[nx[tot]]+1][1]>l || d[nx[nx[tot]]+1][1]==d[tot][1])))
nx[tot]-=((Len[nx[tot]]-(Len[nx[tot]]/2+1))/(Len[nx[tot]]-Len[nx[nx[tot]]]))*(nx[tot]-nx[nx[tot]]);
}
nx[tot]=nx[nx[tot]];
}
k=min(d[nx[tot]+1][1],A[i][1]);
if (d[nx[tot]+1][0]==d[tot][0])
{
ans=(ans+Len[nx[tot]]*(k-l)%mod+(1ll*(l+1+k)*(k-l)/2)%mod)%mod;
l=k;
ans=(ans+Len[1]*(A[i][1]-k))%mod;
}
nx[tot]+=(d[nx[tot]+1][0]==d[tot][0] && d[nx[tot]+1][1]<=d[tot][1]);
}
dfs(a[i][0],ans);
ans=ANS,--tot;
}
}
int main()
{
// #ifdef file
// freopen("jojo6.in","r",stdin);
// #endif
// freopen("b.out","w",stdout);
scanf("%d",&n);
l=tot=1;id[0]=1;
fo(i,1,n)
{
scanf("%d",&tp);
if (tp==1)
{
scanf("%d%c%c",&j,&ch,&ch);
++tot;
New(l,tot,ch-'a'+1,j);
l=tot;
}
else
{
scanf("%d",&j);
l=id[j];
}
b[l].push_back(i);id[i]=l;
}
tot=0;
dfs(1,0);
fo(i,1,n) printf("%lld
",Ans[i]);
fclose(stdin);
fclose(stdout);
return 0;
}