2019 MIST IUPC F - Palindromadness

Posted intwentieth

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019 MIST IUPC F - Palindromadness相关的知识,希望对你有一定的参考价值。

题解:等我知道为什么了再写。反正是个我觉得很难的回文自动机的题。

#include<bits/stdc++.h>
#define ls (x<<1)
#define rs (x<<1|1)
#define ll long long
#define pb push_back
#define mp make_pair
#define db double
#define pii pair<int,int>
using namespace std;
const int M=1e4+7;
const int N=1e6+7;
const int inf=1e9;
inline ll read()

    ll x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘)if(ch==‘-‘)f=-1;ch=getchar();
    while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘;ch=getchar();
    return x*f;

int T;
char S[N];
ll aa[N];
int n,base,mod;
struct PAM
	int last,tot;
	int son[N][26],len[N],fail[N],half[N],pq[N];
	ll cnt[N],val[N];
	ll ans;
	int vis[N];
	ll tmp;
	void init()
		for(int i=0;i<=tot;i++)
			cnt[i]=len[i]=0;
		
		for(int i=0;i<=tot;i++)for(int j=0;j<26;j++)son[i][j]=0;
		len[1]=-1;tot=1;last=0;fail[0]=fail[1]=1;
		ans=0;tmp=0;
	
	void extend(int c,int pl,char *S)
		int p=last;int q,r;
		while(S[pl-len[p]-1]!=S[pl])p=fail[p];
		if(!son[p][c])
			q=++tot,r=fail[p];
			len[q]=len[p]+2;
			while(S[pl-len[r]-1]!=S[pl])r=fail[r];
			fail[q]=son[r][c];	
			son[p][c]=q;
		
		last=son[p][c];
		cnt[last]++;
	
	void cal()
		for(int i=1;i<=tot;i++)pq[i]=cnt[i];
		for(int i=tot;i>=1;i--)cnt[fail[i]]+=cnt[i];
	
	void dfs(int x)
		int sta=0;
		if(fail[x]>1&&!vis[fail[x]])
			vis[fail[x]]=1;
			sta=1;
			tmp=(tmp+cnt[fail[x]]*aa[n-len[fail[x]]]%mod)%mod;
		
		
		if(x>1&&!vis[x])tmp=(tmp+cnt[x]*aa[n-len[x]]%mod)%mod;vis[x]=1;
		//cout<<tmp<<" "<<cnt[x]<<" "<<aa[n-len[x]]<<"\n"; 
		ans=(ans+tmp*cnt[x]%mod)%mod;
		for(int i=0;i<26;i++)
			if(son[x][i])dfs(son[x][i]);
		
		if(x>1&&vis[x])tmp=(tmp-cnt[x]*aa[n-len[x]]%mod)%mod,vis[x]=0;
		if(sta)tmp=(tmp-cnt[fail[x]]*aa[n-len[fail[x]]]%mod)%mod,vis[fail[x]]=0;
	
pam;
 
int main()
	cin>>T;
	int cas=0;
	while(T--)
		cin>>n>>base>>mod;
		scanf("%s",S+1);
		aa[0]=1;
		int len=strlen(S+1);
		for(int i=1;i<=n;i++)aa[i]=aa[i-1]*base%mod;
		//for(int i=1;i<=n;i++)cout<<aa[i]<<" ";cout<<"\n";
		pam.init();
		for(int i=1;i<=len;i++)
			pam.extend(S[i]-‘a‘,i,S);
		
		pam.cal();
		pam.dfs(0);
		//cout<<pam.tmp<<"\n";
		pam.dfs(1);
		
		//cout<<pam.cnt[0]<<pam.cnt[1]<<"\n";
		cout<<"Case "<<++cas<<": "<<(pam.ans%mod+mod)%mod<<"\n";
	

  

以上是关于2019 MIST IUPC F - Palindromadness的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Nintendo DS 上使用 PAlin 以编程方式搜索 Wifi 接入点

Mist 转移默认区块存储位置方法

Mist钱包的安装与使用

Mist钱包的安装与使用

咆哮通知 - 不会使用框架 (Mist) 触发通知

独家译文 | 如何为Mist建立无服务器应用