您的位置:首页 > Web前端 > JavaScript

BZOJ 1444 [Jsoi2009] 有趣的游戏

2017-03-16 20:48 302 查看

Description



Input



注意 是0<=P

Output



Sample Input



Sample Output



HINT


 30%的数据保证, n ≤ 2. 50%的数据保证, n ≤ 5. 100%的数据保证, n , l, m≤ 10.

Source

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

AC自动机+矩阵乘法~

把所有串在AC自动机上建出来,记录终止点位置,然后建出方程。这里应该是要用高斯消元的,但是数据小可以用50次矩阵乘法水过~

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

int n,l,m,x,y,cnt,c[125][11],last[125],ed[125],bp[125],kkzv;
double gl[11],a[2][125][125];
char s[11];

int read()
{
int totnum=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
while(ch>='0' && ch<='9') {totnum=(totnum<<1)+(totnum<<3)+ch-'0';ch=getchar();}
return totnum*f;
}

struct ac{
void add(int u)
{
scanf("%s",s+1);
int x=1;
for(int i=1;i<=l;i++)
{
if(!c[x][s[i]-'A']) c[x][s[i]-'A']=++cnt;
x=c[x][s[i]-'A'];
}
ed[x]=u;bp[u]=x;
}
void getlast()
{
queue<int> q;
for(int i=0;i<m;i++)
if(!c[1][i]) c[1][i]=1;
else last[c[1][i]]=1,q.push(c[1][i]);
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=0;i<m;i++)
if(!c[x][i]) c[x][i]=c[last[x]][i];
else last[c[x][i]]=c[last[x]][i],q.push(c[x][i]);
}
}
}ac;

int main()
{
n=read();l=read();m=read();cnt=1;
for(int i=0;i<m;i++) x=read(),y=read(),gl[i]=(double)x/y;
for(int i=1;i<=n;i++) ac.add(i);ac.getlast();
for(int i=1;i<=cnt;i++)
if(!ed[i]) for(int j=0;j<m;j++) a[kkzv][i][c[i][j]]+=gl[j];
else a[kkzv][i][i]=1;
for(int kkz=1;kkz<=50;kkz++)
{
kkzv^=1;
memset(a[kkzv],0,sizeof(a[kkzv]));
for(int i=1;i<=cnt;i++)
for(int j=1;j<=cnt;j++)
for(int k=1;k<=cnt;k++) a[kkzv][i][j]+=a[kkzv^1][i][k]*a[kkzv^1][k][j];
}
for(int i=1;i<=n;i++) printf("%.2lf\n",a[kkzv][1][bp[i]]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息