zoukankan      html  css  js  c++  java
  • 【BZOJ1444】[JSOI2009]有趣的游戏(高斯消元,AC自动机)

    【BZOJ1444】[JSOI2009]有趣的游戏(高斯消元,AC自动机)

    题面

    BZOJ

    题解

    先把(AC)自动机构建出来,最好构成(Trie)图。然后这样子显然是在一个有向图中有一堆概率的转移,并且存在环,所以高斯消元解决。

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    struct Node{int son[26],fail,lst;}t[500];
    int tot,n,m,l,pos[20];
    char ch[50];
    double g[200][200],p[50];
    void insert(char *s,int id)
    {
    	int u=0;
    	for(int i=1;i<=l;++i)
    	{
    		if(!t[u].son[s[i]-65])
    			t[u].son[s[i]-65]=++tot;
    		u=t[u].son[s[i]-65];
    	}
    	t[u].lst=id;pos[id]=u;
    }
    void Build()
    {
    	queue<int> Q;
    	for(int i=0;i<m;++i)if(t[0].son[i])Q.push(t[0].son[i]);
    	while(!Q.empty())
    	{
    		int u=Q.front();Q.pop();
    		for(int i=0;i<m;++i)
    			if(t[u].son[i])
    				t[t[u].son[i]].fail=t[t[u].fail].son[i],Q.push(t[u].son[i]);
    			else t[u].son[i]=t[t[u].fail].son[i];
    		t[u].lst|=t[t[u].fail].lst;
    	}
    }
    void Gauss()
    {
    	for(int i=0;i<=tot;++i)
    	{
    		int p=0;
    		for(int j=i;j<=tot;++j)
    			if(g[j][i]){p=j;break;}
    		for(int j=0;j<=tot+1;++j)swap(g[i][j],g[p][j]);
    		double t=g[i][i];
    		for(int j=0;j<=tot+1;++j)g[i][j]/=t;
    		for(int j=i+1;j<=tot;++j)
    		{
    			double d=g[j][i];
    			for(int k=0;k<=tot+1;++k)
    				g[j][k]-=g[i][k]*d;
    		}
    	}
    	for(int i=tot;~i;--i)
    	{
    		g[i][tot+1]/=g[i][i];
    		for(int j=i-1;j>=0;--j)
    			g[j][tot+1]-=g[j][i]*g[i][tot+1];
    		if(!g[i][tot+1])g[i][tot+1]=0;
    	}
    }
    int main()
    {
    	scanf("%d%d%d",&n,&l,&m);
    	for(int i=0;i<m;++i)
    	{
    		int a,b;
    		scanf("%d%d",&a,&b);
    		p[i]=1.0*a/b;
    	}
    	for(int i=1;i<=n;++i)
    	{
    		scanf("%s",ch+1);
    		insert(ch,i);
    	}
    	Build();
    	for(int i=0;i<=tot;++i)
    		for(int j=0;j<m;++j)
    			if(!t[i].lst)
    				g[t[i].son[j]][i]+=p[j];
    	for(int i=0;i<=tot;++i)g[i][i]-=1;
    	for(int i=0;i<=tot;++i)if(t[i].lst)g[0][i]=1;else g[0][i]=0;g[0][tot+1]=1;
    	Gauss();
    	for(int i=1;i<=n;++i)printf("%.2lf
    ",g[pos[i]][tot+1]);
    	return 0;
    }
    
  • 相关阅读:
    ARRAYLIST使用方法
    学习如何把数据库数据提取为XML(转)
    jquery常用技巧及常用方法列表
    邮件发送
    DataSet/XMl相互操作
    jquery Tab效果和动态加载
    Ajax 显示XML
    dropdownlist动态数据绑定
    sql 拼接
    javascriptxmlxslt操作
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9762691.html
Copyright © 2011-2022 走看看