[TYVJ]1519 博彩

时间:2023-03-09 09:06:21
[TYVJ]1519 博彩

传送门

AC自动机模板题,好吧我只是单纯的搞个AC自动机的模板。

//TYVJ 1519
//by Cydiater
//2016.10.18
#include <iostream>
#include <iomanip>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define ll long long
#define up(i,j,n)		for(int i=j;i<=n;i++)
#define down(i,j,n)		for(int i=j;i>=n;i--)
const ll MAXN=1e6+5;
const ll oo=1LL<<60;
inline int read(){
	char ch=getchar();int x=0,f=1;
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int N,M,R,fail[MAXN],next[MAXN][12],cnt=0,now,q[MAXN],head,tail,t=1;
bool end[MAXN];
ll f[2][MAXN],ans=0,tol=1;
char s[25];
namespace solution{
	void insert(){
		now=0;
		up(i,1,strlen(s+1)){
			int num=s[i]-'0';
			if(next[now][num]==0)next[now][num]=++cnt;
			now=next[now][num];
		}
		end[now]=1;
	}
	void buildAC(){
		head=1;tail=0;
		up(i,1,R)if(next[0][i]>0)q[++tail]=next[0][i];
		for(;head<=tail;head++){
			now=q[head];end[now]|=end[fail[now]];
			up(i,1,R){
				int son=next[now][i];
				if(son>0){
					fail[son]=next[fail[now]][i];
					q[++tail]=son;
				}else next[now][i]=next[fail[now]][i];
			}
		}
	}
	void init(){
		memset(end,0,sizeof(end));
		N=read();M=read();R=read();
		up(i,1,M){
			scanf("%s",s+1);
			insert();
		}
		buildAC();
	}
	void DP(int id,int t){
		up(node,0,cnt)if(end[node]==0&&f[t^1][node]!=0)
			up(i,1,R)f[t][next[node][i]]+=f[t^1][node];
	}
	void slove(){
		f[t][0]=1;
		up(i,1,N){
			t^=1;
			memset(f[t],0,sizeof(f[t]));
			DP(i,t);tol*=R;
		}
		up(i,0,cnt)if(!end[i])ans+=f[t][i];
	}
	void output(){
		double tmp=((double)tol-(double)ans)/((double)tol);
		printf("%.5lf\n",tmp);
	}
}
int main(){
	//freopen("input.in","r",stdin);
	using namespace solution;
	init();
	slove();
	output();
	return 0;
}