codeforces1202E

题目描述

在这里插入图片描述
在这里插入图片描述

题目大意

给出母串T和若干子串S,定义f(x,y)表示字符串y在x中出现次数
求∑∑f(T,Si+Sj)

题解

当初被D降智后没发现这是到SB题
枚举连接位置,ans=∑以i为结尾的个数*以i+1为开头的个数
AC自动机随便搞
时间:O(n)

code

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
using namespace std;

int tr[200002][26];
int sum[200002];
int fa[200002];
int S[200002];
int T[200002];
int b[200002];
int d[200002];
long long s1[200002];
long long s2[200002];
int N,n,m,i,j,k,l,len,h,t;
long long ans;
char ch;

void New(int t,int x)
{
    
    
	if (!tr[t][x])
	tr[t][x]=++len;
}

int main()
{
    
    
//	freopen("CF1202E.in","r",stdin);
//	freopen("a.in","r",stdin);
	
	ch=getchar();
	while (ch>='a' && ch<='z')
	{
    
    
		S[++N]=ch-'a';
		ch=getchar();
	}
	
	scanf("%d",&n);
	fo(i,1,n)
	{
    
    
		while (ch<'a' || ch>'z')
		ch=getchar();
		
		while (ch>='a' && ch<='z')
		{
    
    
			T[++m]=ch-'a';
			ch=getchar();
		}
		
		b[i]=m;
	}
	
	len=1;
	fo(i,1,n)
	{
    
    
		k=1;
		fo(j,b[i-1]+1,b[i])
		{
    
    
			New(k,T[j]);
			k=tr[k][T[j]];
		}
		
		++sum[k];
	}
	
	h=0;
	t=1;
	d[1]=1;
	while (h<t)
	{
    
    
		++h;
		fo(i,0,25)
		if (tr[d[h]][i])
		{
    
    
			j=fa[d[h]];
			while (j && !tr[j][i])
			j=fa[j];
			
			if (!j)
			fa[tr[d[h]][i]]=1;
			else
			fa[tr[d[h]][i]]=tr[j][i];
			
			d[++t]=tr[d[h]][i];
			sum[tr[d[h]][i]]+=sum[fa[tr[d[h]][i]]];
		}
	}
	
	k=1;
	fo(i,1,N)
	{
    
    
		while (k && !tr[k][S[i]])
		k=fa[k];
		
		if (!k)
		k=1;
		else
		k=tr[k][S[i]];
		
		s1[i]=sum[k];
	}
	
//	---
	
	memset(sum,0,sizeof(sum));
	memset(fa,0,sizeof(fa));
	memset(tr,0,sizeof(tr));
	len=1;
	fo(i,1,n)
	{
    
    
		k=1;
		fd(j,b[i],b[i-1]+1)
		{
    
    
			New(k,T[j]);
			k=tr[k][T[j]];
		}
		
		++sum[k];
	}
	
	h=0;
	t=1;
	d[1]=1;
	while (h<t)
	{
    
    
		++h;
		fo(i,0,25)
		if (tr[d[h]][i])
		{
    
    
			j=fa[d[h]];
			while (j && !tr[j][i])
			j=fa[j];
			
			if (!j)
			fa[tr[d[h]][i]]=1;
			else
			fa[tr[d[h]][i]]=tr[j][i];
			
			d[++t]=tr[d[h]][i];
			sum[tr[d[h]][i]]+=sum[fa[tr[d[h]][i]]];
		}
	}
	
	k=1;
	fd(i,N,1)
	{
    
    
		while (k && !tr[k][S[i]])
		k=fa[k];
		
		if (!k)
		k=1;
		else
		k=tr[k][S[i]];
		
		s2[i]=sum[k];
	}
	
//	---
	
	fo(i,1,N-1)
	ans+=s1[i]*s2[i+1];
	
	printf("%I64d\n",ans);
}

猜你喜欢

转载自blog.csdn.net/gmh77/article/details/100230654