• POJ 1625 Censored!(AC自动机+高精度+dp)


    http://poj.org/problem?id=1625

    题意:

    给出一些单词,求长度为m的串不包含这些单词的个数。

    思路:

    这道题和HDU 2243和POJ 2778是一样的,不同的是这道题不取模,所以不可以用矩阵快速幂,必须使用高精度,所以这里用滚动dp解决即可。

    高精度的写法参考了kuangbin巨巨的模板。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<vector>
      6 #include<stack>
      7 #include<queue>
      8 #include<cmath>
      9 #include<map>
     10 #include<set>
     11 using namespace std;
     12 typedef long long ll;
     13 const int INF = 0x3f3f3f3f;
     14 const int maxn=10000+5;
     15 
     16 int n, m, num, p, len;
     17 map<char,int> mp;
     18 char s[105];
     19 
     20 struct Trie
     21 {
     22     int son[55];
     23     int cnt;
     24     int fail;
     25 }t[55*55];
     26 
     27 struct Matrix
     28 {
     29     int mat[110][110], n;
     30     Matrix(){}
     31     Matrix(int _n)
     32     {
     33         n=_n;
     34         for(int i=0;i<n;i++)
     35         for(int j=0;j<n;j++)
     36             mat[i][j]=0;
     37     }
     38 };
     39 
     40 void init(int x)
     41 {
     42     t[x].fail=0;
     43     t[x].cnt=0;
     44     memset(t[x].son,0,sizeof(t[x].son));
     45 }
     46 
     47 void trie(char *s)
     48 {
     49     int n=strlen(s);
     50     int x=0;
     51     for(int i=0;i<n;i++)
     52     {
     53         int c=mp[s[i]];
     54         if(!t[x].son[c])
     55         {
     56             num++;
     57             init(num);
     58             t[x].son[c]=num;
     59         }
     60         x=t[x].son[c];
     61     }
     62     t[x].cnt=1;
     63 }
     64 
     65 void buildAC()
     66 {
     67     queue<int> Q;
     68     for(int i=1;i<=len;i++)  if(t[0].son[i])  Q.push(t[0].son[i]);
     69     while(!Q.empty())
     70     {
     71         int x=Q.front(); Q.pop();
     72         int fail=t[x].fail;
     73         for(int i=1;i<=len;i++)
     74         {
     75 
     76             int y=t[x].son[i];
     77             if(y)
     78             {
     79                 t[y].fail=t[fail].son[i];
     80                 t[y].cnt|=t[t[fail].son[i]].cnt;  //这儿很重要,这个标记需要传递
     81                 Q.push(y);
     82             }
     83             else t[x].son[i]=t[fail].son[i];
     84         }
     85     }
     86 }
     87 
     88 Matrix getMatrix()
     89 {
     90     Matrix c=Matrix(num+1);
     91     for(int i=0;i<=num;i++)
     92     {
     93         for(int j=1;j<=len;j++)
     94         {
     95             if(t[t[i].son[j]].cnt==0)  c.mat[i][t[i].son[j]]++;
     96         }
     97     }
     98     return c;
     99 }
    100 
    101 /******************************高精度算法************************************/
    102 struct BigInt
    103 {
    104     const static int mod = 10000;
    105     const static int DLEN = 4;
    106     int a[600],len;
    107     BigInt()
    108     {
    109         memset(a,0,sizeof(a));
    110         len = 1;
    111     }
    112     BigInt(int v)
    113     {
    114         memset(a,0,sizeof(a));
    115         len = 0;
    116         do
    117         {
    118             a[len++] = v%mod;
    119             v /= mod;
    120         }while(v);
    121     }
    122     BigInt(const char s[])
    123     {
    124         memset(a,0,sizeof(a));
    125         int L = strlen(s);
    126         len = L/DLEN;
    127         if(L%DLEN)len++;
    128         int index = 0;
    129         for(int i = L-1;i >= 0;i -= DLEN)
    130         {
    131             int t = 0;
    132             int k = i - DLEN + 1;
    133             if(k < 0)k = 0;
    134             for(int j = k;j <= i;j++)
    135                 t = t*10 + s[j] - '0';
    136             a[index++] = t;
    137         }
    138     }
    139     BigInt operator +(const BigInt &b)const
    140     {
    141         BigInt res;
    142         res.len = max(len,b.len);
    143         for(int i = 0;i <= res.len;i++)
    144             res.a[i] = 0;
    145         for(int i = 0;i < res.len;i++)
    146         {
    147             res.a[i] += ((i < len)?a[i]:0)+((i < b.len)?b.a[i]:0);
    148             res.a[i+1] += res.a[i]/mod;
    149             res.a[i] %= mod;
    150         }
    151         if(res.a[res.len] > 0)res.len++;
    152         return res;
    153     }
    154     BigInt operator *(const BigInt &b)const
    155     {
    156         BigInt res;
    157         for(int i = 0; i < len;i++)
    158         {
    159             int up = 0;
    160             for(int j = 0;j < b.len;j++)
    161             {
    162                 int temp = a[i]*b.a[j] + res.a[i+j] + up;
    163                 res.a[i+j] = temp%mod;
    164                 up = temp/mod;
    165             }
    166             if(up != 0)
    167                 res.a[i + b.len] = up;
    168         }
    169         res.len = len + b.len;
    170         while(res.a[res.len - 1] == 0 &&res.len > 1)res.len--;
    171         return res;
    172     }
    173     void output()
    174     {
    175         printf("%d",a[len-1]);
    176         for(int i = len-2;i >=0 ;i--)
    177             printf("%04d",a[i]);
    178         printf("
    ");
    179     }
    180 };
    181 /*************************************************************************/
    182 
    183 BigInt dp[2][110];
    184 
    185 int main()
    186 {
    187     //freopen("in.txt","r",stdin);
    188     scanf("%d%d%d",&n,&m,&p);
    189     mp.clear();
    190     scanf("%s",s+1);
    191     len=strlen(s+1);
    192     for(int i=1;i<=len;i++)  mp[s[i]]=i;
    193     for(int i=1;i<=p;i++)
    194     {
    195         scanf("%s",s);
    196         trie(s);
    197     }
    198     buildAC();
    199     Matrix a=getMatrix();
    200 
    201     //滚动数组实现
    202     int now = 0;
    203     dp[now][0] = 1;
    204     for(int i=0;i<a.n;i++) dp[now][i] = 0;
    205     for(int i=0;i<m;i++)
    206     {
    207         now^=1;
    208         for(int j=0;j<a.n;j++) dp[now][j] = 0;
    209         for(int j=0;j<a.n;j++)
    210         for(int k=0;k<a.n;k++)
    211             if(a.mat[j][k] > 0) dp[now][k] = dp[now][k]+dp[now^1][j]*a.mat[j][k];
    212     }
    213     BigInt ans = 0;
    214     for(int i = 0;i < a.n;i++)
    215         ans = ans + dp[now][i];
    216     ans.output();
    217     return 0;
    218 }
  • 相关阅读:
    1.unix网络编程基础知识
    eclipse中如何获得feature与plugin的list
    eclipse中Debug的三种方式
    Eclipse Update Site中Nested Features问题
    java中URL,URLConnection,HttPURLConnection的使用
    iBatis简单入门教程
    Git 常用命令整理
    【整理】chmod和chown命令的用法
    【原创】Gson使用,json转换为java对象
    CSS reset 一份很全的样式表,附YUI的css reset
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7447006.html
Copyright © 2020-2023  润新知