• 【bzoj1444】[Jsoi2009]有趣的游戏 AC自动机+矩阵乘法


    题目描述

    输入

    注意 是0<=P

    输出

    样例输入


    样例输出


    题解

    AC自动机+矩阵乘法

    先将所有字符串放到AC自动机中,求出Trie图。

    然后构建邻接矩阵:如果x不是某个字符串的末位置,则x连向next[x][i],边权为pi/qi;否则x只连向x,边权为1。

    然后这个矩阵的无穷次方即为答案。

    由于这个矩阵乘了很多次后概率基本不变,可以认定为答案。所以我们可以将这个矩阵自乘50次(相当于求出这个矩阵的2^50次方),得出答案。

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define N 12
    #define M 110
    using namespace std;
    queue<int> q;
    double p[N];
    int pos[N] , next[M][N] , fail[M] , tag[M], tot = 1 , m;
    char str[N];
    struct data
    {
    	double v[M][M];
    	data() {memset(v , 0 , sizeof(v));}
    	data operator*(const data a)const
    	{
    		data ans;
    		int i , j , k;
    		for(i = 1 ; i <= tot ; i ++ )
    			for(j = 1 ; j <= tot ; j ++ )
    				for(k = 1 ; k <= tot ; k ++ )
    					ans.v[i][j] += v[i][k] * a.v[k][j];
    		return ans;
    	}
    }A;
    void build()
    {
    	int x , i;
    	for(i = 0 ; i < m ; i ++ ) next[0][i] = 1;
    	q.push(1);
    	while(!q.empty())
    	{
    		x = q.front() , q.pop();
    		for(i = 0 ; i < m ; i ++ )
    		{
    			if(next[x][i]) fail[next[x][i]] = next[fail[x]][i] , q.push(next[x][i]);
    			else next[x][i] = next[fail[x]][i];
    		}
    	}
    }
    int main()
    {
    	int n , l , i , j , x , y;
    	scanf("%d%d%d" , &n , &l , &m);
    	for(i = 0 ; i < m ; i ++ ) scanf("%d%d" , &x , &y) , p[i] = (double)x / y;
    	for(i = 1 ; i <= n ; i ++ )
    	{
    		scanf("%s" , str + 1);
    		for(x = j = 1 ; j <= l ; j ++ )
    		{
    			if(!next[x][str[j] - 'A']) next[x][str[j] - 'A'] = ++tot;
    			x = next[x][str[j] - 'A'];
    		}
    		pos[i] = x , tag[x] = 1;
    	}
    	build();
    	for(i = 1 ; i <= tot ; i ++ )
    	{
    		if(tag[i]) A.v[i][i] = 1;
    		else for(j = 0 ; j < m ; j ++ ) A.v[i][next[i][j]] += p[j];
    	}
    	for(i = 1 ; i <= 50 ; i ++ ) A = A * A;
    	for(i = 1 ; i <= n ; i ++ ) printf("%.2lf
    " , A.v[1][pos[i]]);
    	return 0;
    }
    

     

  • 相关阅读:
    k8s service的DNS名称解析之CoreDNS
    k8s service负载均衡实现之iptables
    k8s 将项目暴露到互联网访问
    k8s 日志按体现分类与采集思路
    k8s ingressd的http对外暴露网站
    k8s 容器交付流程和项目部署流程
    k8s ingress使用DaemonSet部署
    Google Base与科学家数据共享 (Nature Vol 438|24 November 2005)
    总结:rdf:ID和rdf:about的区别(转载)
    一个元搜索引擎
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7115594.html
Copyright © 2020-2023  润新知