zoukankan      html  css  js  c++  java
  • AC自动机——Uva 11468 子串

    题目链接:http://vjudge.net/contest/142513#problem/A

    题意:给出一些字符和各自对应的选择概率,随机选择L次后将得到一个长度为L的随机字符串S.给出K个模版串,计算S不包含任何一个串的概率.

    分析:

     在构造好的AC自动机里面,每随机生成一个字母,相当于在AC自动机中随机走一步。所有单词结点标记为禁止,本题就是从结点 0 走 l 步,不进入任何禁止结点的概率。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int SIGMA_SIZE = 64;
    const int MAXNODE = 500;
    
    int idx[256];
    char s[30][30];
    double prob[SIGMA_SIZE];
    int n;
    
    
    struct AhoCorasickAutomata
    {
        int ch[MAXNODE][SIGMA_SIZE];
        int f[MAXNODE];
        int match[MAXNODE];
        int sz;
    
        void init()
        {
            sz = 1;
            memset(ch[0],0,sizeof(ch[0]));
        }
    
        void insert(char *s)
        {
            int u = 0,n = strlen(s);
            for(int i=0; i<n; i++)
            {
                int c = idx[s[i]];
                if(!ch[u][c])
                {
                    memset(ch[sz],0,sizeof(ch[sz]));
                    match[sz] = 0;
                    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
            match[u] = 1;
        }
    
        void getFail()
        {
            queue<int> q;
            f[0] = 0;
            for(int c=0; c<SIGMA_SIZE; c++)
            {
                int u = ch[0][c];
                if(u)
                {
                    f[u] = 0;
                    q.push(u);
                }
            }
    
            while(!q.empty())
            {
                int r = q.front();
                q.pop();
                for(int c=0; c<SIGMA_SIZE; c++)
                {
                    int u = ch[r][c];
                    if(!u)
                    {
                        ch[r][c]=ch[f[r]][c];
                        continue;
                    }
                    q.push(u);
                    int v = f[r];
                    while(v&&!ch[v][c])
                        v = f[v];
                    f[u] = ch[v][c];
                    match[u] |=match[f[u]];
                }
            }
        }
    };
    
    AhoCorasickAutomata ac;
    
    double d[MAXNODE][105];
    int vis[MAXNODE][105];
    
    double getProb(int u,int l)
    {
        if(!l) return 1.0;
        if(vis[u][l]) return d[u][l];
        vis[u][l] = 1;
        double& ans = d[u][l];
        ans = 0.0;
        for(int i=0; i<n; i++)
        {
            if(!ac.match[ac.ch[u][i]])
                ans += prob[i]*getProb(ac.ch[u][i],l-1);
        }
        return ans;
    }
    
    
    int main()
    {
        int T;
        scanf("%d",&T);
        for(int kase = 1; kase<=T; kase ++)
        {
            int k,l;
            scanf("%d",&k);
            for(int i=0; i<k; i++)
                scanf("%s",s[i]);
    
            scanf("%d",&n);
            for(int i=0; i<n; i++)
            {
                char ch[9];
                scanf("%s%lf",ch,&prob[i]);
                idx[ch[0]] = i;
            }
    
            ac.init();
            for(int i=0; i<k; i++)
                ac.insert(s[i]);
            ac.getFail();
            scanf("%d",&l);
            memset(vis,0,sizeof(vis));
            printf("Case #%d: %.6lf
    ",kase,getProb(0,l));
        }
    
        return 0;
    }
  • 相关阅读:
    jquery实现选项卡(两句即可实现)
    常用特效积累
    jquery学习笔记
    idong常用js总结
    织梦添加幻灯片的方法
    LeetCode "Copy List with Random Pointer"
    LeetCode "Remove Nth Node From End of List"
    LeetCode "Sqrt(x)"
    LeetCode "Construct Binary Tree from Inorder and Postorder Traversal"
    LeetCode "Construct Binary Tree from Preorder and Inorder Traversal"
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6087297.html
Copyright © 2011-2022 走看看