BZOJ 1444: [Jsoi2009]有趣的游戏

1444: [Jsoi2009]有趣的游戏

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1126  Solved: 394
[Submit][Status][Discuss]

Description

Input

注意 是0<=P

Output

Sample Input


Sample Output


HINT

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

Source

分析:

就是建出Trie图然后构造转移方程高斯消元一发...

然后我好像之前写的AC自动机的构建有些问题,并没有根节点向根节点转移的边,所以貌似出了一些问题...

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
//by NeighThorn
using namespace std;

const int maxn=10+5,maxm=maxn*maxn+5;

int n,l,m,tot,head,tail,q[maxm],id[maxn],vis[maxn];
double t[maxn],a[maxm][maxm];

char s[maxn];

struct Trie{
	int cnt,fail,nxt[26];
}tr[maxm];

inline int insert(char *s){
	int p=0;
	for(int i=0;i<l;i++){
		if(!tr[p].nxt[s[i]-'A'])
			tr[p].nxt[s[i]-'A']=++tot;
		p=tr[p].nxt[s[i]-'A'];
	}
	tr[p].cnt++;
	return p;
}

inline void buildACM(void){
    head=tail=0,q[0]=0;
    while(head<=tail){
        int top=q[head++]; 
        for(int i=0;i<m;i++){
        	int p=tr[tr[top].fail].nxt[i];
        	if(!tr[top].nxt[i]) tr[top].nxt[i]=p;
        	else{
        		if(top)
        			tr[tr[top].nxt[i]].fail=p;
        		q[++tail]=tr[top].nxt[i];
        	}
        }
    }
}

inline void gauss(void){
	for(int i=0;i<=tot;i++){
		int k=i;
		while(!fabs(a[k][i])&&k<tot) k++;
		if(k!=i)
			for(int j=0;j<=tot+1;j++)
				swap(a[k][j],a[i][j]);
		for(int l=0;l<=tot;l++)
			if(l!=i&&fabs(a[l][i])){
				double lala=a[l][i]/a[i][i];
				for(int s=0;s<=tot+1;s++)
					a[l][s]-=lala*a[i][s];
			}
	}
}

signed main(void){
	scanf("%d%d%d",&n,&l,&m);
	for(int i=1,x,y;i<=m;i++){
		scanf("%d%d",&x,&y),t[i-1]=1.0*x/(double)y;
		if(t[i-1]==0.0)
			vis[i-1]=1;
	}
	for(int i=1,flag;i<=n;i++){
		scanf("%s",s);flag=0;
		for(int j=0;j<l&&!flag;j++)
			flag|=vis[s[j]-'A'];
		if(flag)
			id[i]=-1;
		else
			id[i]=insert(s);
	}
	buildACM();a[0][tot+1]=1.0;
	for(int i=0;i<=tot;i++){
		a[i][i]+=1.0;
		if(!tr[i].cnt)
			for(int j=0;j<m;j++)
				a[tr[i].nxt[j]][i]+=-1.0*t[j];
	}
	gauss();
	for(int i=1;i<=n;i++){
		if(id[i]==-1)
			puts("0.00");
		else
			printf("%.2f
",a[id[i]][tot+1]/a[id[i]][id[i]]);
	}
	return 0;
}

  


By NeighThorn

原文地址:https://www.cnblogs.com/neighthorn/p/6477202.html