[HNOI2008]GT考试

Code:

#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#define ll long long 
using namespace std;
void setIO(string a){ freopen((a+".in").c_str(),"r",stdin);}
int nodes,mod;
char arr[30];
struct matrix{
	int mat[105][105];
}unit;

void init(matrix &a){ 
	for(int i=0;i<=nodes;++i)
	    for(int j=0;j<=nodes;++j) a.mat[i][j]=0;
}
void get(matrix &a){ init(a); for(int i=0;i<=nodes;++i) a.mat[i][i]=1; }
matrix operator*(matrix a,matrix b){
	matrix c;
	init(c);
	for(int i=0;i<=nodes;++i)
		for(int j=0;j<=nodes;++j)
			for(int k=0;k<=nodes;++k) 
				c.mat[i][j]=((ll)(a.mat[i][k]*b.mat[k][j])%mod+c.mat[i][j])%mod;
			
	return c;
}
matrix operator^(matrix a,int p){
    matrix ans;
    get(ans);
    while(p){
    	if(p&1)ans=ans*a;
    	a=a*a;
    	p>>=1;
    }
    return ans;
}
struct Automaton{
	#define idx str[i]-'0'
	#define maxn 30000
	#define sigma 10
	int ch[maxn][sigma], fail[maxn];
	bool tag[maxn];
	void insert(char str[]){
		int n=strlen(str),j=0;
		for(int i=0;i<n;++i){
			if(!ch[j][idx]) ch[j][idx]=++nodes;
			j=ch[j][idx];
		}
		tag[j]=true;
	}

	queue<int>Q;
	void build(){
		for(int i=0;i<sigma;++i) if(ch[0][i]) Q.push(ch[0][i]);
		while(!Q.empty()){
			int u=Q.front();Q.pop();
			for(int i=0;i<sigma;++i){
				int r=ch[u][i];
				if(!r) { ch[u][i]=ch[fail[u]][i]; continue;}
				Q.push(r);
				fail[r]=ch[fail[u]][i];
				if(tag[fail[r]]) tag[r]=true;
			}
		}
		init(unit);
		for(int i=0;i<=nodes;++i)
			for(int j=0;j<sigma;++j)
				if(!tag[i]&&!tag[ch[i][j]]) unit.mat[i][ch[i][j]]+=1;
	}
}aho;
int main(){
	//setIO("input");
	int n,m;
	scanf("%d%d%d",&n,&m,&mod);
	scanf("%s",arr);
	aho.insert(arr), aho.build();
	matrix final=unit^n;
	int ans=0;
	for(int i=0;i<=nodes;++i) ans+=final.mat[0][i], ans%=mod;
	printf("%d",ans);
    return 0;
}

  

原文地址:https://www.cnblogs.com/guangheli/p/9909802.html