zoukankan      html  css  js  c++  java
  • POJ1625 Censored! —— AC自动机 + DP + 大数

    题目链接:https://vjudge.net/problem/POJ-1625

    Censored!
    Time Limit: 5000MS   Memory Limit: 10000K
    Total Submissions: 10870   Accepted: 2979

    Description

    The alphabet of Freeland consists of exactly N letters. Each sentence of Freeland language (also known as Freish) consists of exactly M letters without word breaks. So, there exist exactly N^M different Freish sentences. 

    But after recent election of Mr. Grass Jr. as Freeland president some words offending him were declared unprintable and all sentences containing at least one of them were forbidden. The sentence S contains a word W if W is a substring of S i.e. exists such k >= 1 that S[k] = W[1], S[k+1] = W[2], ...,S[k+len(W)-1] = W[len(W)], where k+len(W)-1 <= M and len(W) denotes length of W. Everyone who uses a forbidden sentence is to be put to jail for 10 years. 

    Find out how many different sentences can be used now by freelanders without risk to be put to jail for using it. 

    Input

    The first line of the input file contains three integer numbers: N -- the number of letters in Freish alphabet, M -- the length of all Freish sentences and P -- the number of forbidden words (1 <= N <= 50, 1 <= M <= 50, 0 <= P <= 10). 

    The second line contains exactly N different characters -- the letters of the Freish alphabet (all with ASCII code greater than 32). 

    The following P lines contain forbidden words, each not longer than min(M, 10) characters, all containing only letters of Freish alphabet. 

    Output

    Output the only integer number -- the number of different sentences freelanders can safely use.

    Sample Input

    2 3 1
    ab
    bb
    

    Sample Output

    5
    

    Source

    Northeastern Europe 2001, Northern Subregion

    题意:

    给出p个单词,求长度为m且不含有已给单词的字符串有多少个?其中字母表有n个字母。

    题解:

    POJ2278 DNA Sequence无异,只不过此题没有取模,而答案可能很大,所以用到高精度。而且字符串长度较小,可以直接用动态规划进行求解,而不需要用到矩阵进行加速。

    代码如下:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <cmath>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <string>
     11 #include <set>
     12 using namespace std;
     13 typedef long long LL;
     14 const double EPS = 1e-6;
     15 const int INF = 2e9;
     16 const LL LNF = 9e18;
     17 const int MOD = 1e5;
     18 const int MAXN = 50*50+10;
     19 
     20 struct BigInt
     21 {
     22     const static int mod = 10000;
     23     const static int DLEN = 4;
     24     int a[100],len;
     25     BigInt()
     26     {
     27         memset(a,0,sizeof(a));
     28         len = 1;
     29     }
     30     BigInt(int v)
     31     {
     32         memset(a,0,sizeof(a));
     33         len = 0;
     34         do
     35         {
     36             a[len++] = v%mod;
     37             v /= mod;
     38         }while(v);
     39     }
     40     BigInt operator +(const BigInt &b)const
     41     {
     42         BigInt res;
     43         res.len = max(len,b.len);
     44         for(int i = 0;i <= res.len;i++)
     45             res.a[i] = 0;
     46         for(int i = 0;i < res.len;i++)
     47         {
     48             res.a[i] += ((i < len)?a[i]:0)+((i < b.len)?b.a[i]:0);
     49             res.a[i+1] += res.a[i]/mod;
     50             res.a[i] %= mod;
     51         }
     52         if(res.a[res.len] > 0)res.len++;
     53         return res;
     54     }
     55     void output()
     56     {
     57         printf("%d",a[len-1]);
     58         for(int i = len-2;i >=0 ;i--)
     59             printf("%04d",a[i]);
     60         printf("
    ");
     61     }
     62 };
     63 
     64 BigInt dp[2][MAXN];
     65 int M[128];
     66 struct Trie
     67 {
     68     int sz, base;
     69     int next[MAXN][50], fail[MAXN], end[MAXN];
     70     int root, L;
     71     int newnode()
     72     {
     73         for(int i = 0; i<sz; i++)
     74             next[L][i] = -1;
     75         end[L++] = false;
     76         return L-1;
     77     }
     78 
     79     void init(int _sz, int _base)
     80     {
     81         sz = _sz;
     82         base = _base;
     83         L = 0;
     84         root = newnode();
     85     }
     86     void insert(char buf[])
     87     {
     88         int len = strlen(buf);
     89         int now = root;
     90         for(int i = 0; i<len; i++)
     91         {
     92             if(next[now][M[buf[i]]] == -1) next[now][M[buf[i]]] = newnode();
     93             now = next[now][M[buf[i]]];
     94         }
     95         end[now] |= true;
     96     }
     97     void build()
     98     {
     99         queue<int>Q;
    100         fail[root] = root;
    101         for(int i = 0; i<sz; i++)
    102         {
    103             if(next[root][i] == -1) next[root][i] = root;
    104             else fail[next[root][i]] = root, Q.push(next[root][i]);
    105         }
    106         while(!Q.empty())
    107         {
    108             int now = Q.front();
    109             Q.pop();
    110             end[now] |= end[fail[now]];
    111             for(int i = 0; i<sz; i++)
    112             {
    113                 if(next[now][i] == -1) next[now][i] = next[fail[now]][i];
    114                 else fail[next[now][i]] = next[fail[now]][i], Q.push(next[now][i]);
    115             }
    116         }
    117     }
    118 
    119     void query(int len)
    120     {
    121         for(int i = 0; i<=1; i++)
    122         for(int j = 0; j<L; j++)
    123             dp[i][j] = 0;
    124 
    125         int cur = 0;
    126         dp[cur][root] = 1;
    127         for(int i = 0; i<len; i++)
    128         {
    129             for(int j = 0; j<L; j++)
    130                 dp[cur^1][j] = 0;
    131             for(int j = 0; j<L; j++)
    132             {
    133                 if(end[j]) continue;
    134                 for(int k = 0; k<sz; k++)
    135                 {
    136                     if(end[next[j][k]]) continue;
    137                     dp[cur^1][next[j][k]] = dp[cur^1][next[j][k]] + dp[cur][j];
    138                 }
    139             }
    140             cur ^= 1;
    141         }
    142 
    143         BigInt ret = 0;
    144         for(int i = 0; i<L; i++)
    145             ret = ret + dp[cur][i];
    146         ret.output();
    147     }
    148 };
    149 
    150 Trie ac;
    151 char buf[MAXN];
    152 int main()
    153 {
    154     int n, m, p;
    155     while(scanf("%d%d%d", &n,&m,&p)!=EOF)
    156     {
    157         ac.init(n, 0);
    158         scanf("%s", buf);
    159         for(int i = 0; buf[i]; i++)
    160             M[buf[i]] = i;
    161         for(int i = 1; i<=p; i++)
    162         {
    163             scanf("%s", buf);
    164             ac.insert(buf);
    165         }
    166         ac.build();
    167         ac.query(m);
    168     }
    169 }
    View Code
  • 相关阅读:
    MySQL 8.0.14版本新功能详解
    Uncaught TypeError: Right-hand side of 'instanceof' is not an object
    程序员快速技术提升之道
    Windows 10 cmd命令符的使用
    数据千万条,备份第一条:VFEmail被擦除所有数据面临关停
    netty-socketio 示例代码
    idea中 在接口中如何直接跳转到该接口的是实现类中?
    perl DBD处理超时问题
    springboot 启动配置文件配置
    Office Word 发布文章到博客园
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8459493.html
Copyright © 2011-2022 走看看