题目链接:Censored!

解析:AC自己主动机 + 高精度 + 简单DP。

字符有可能会超过128。用map映射一下就可以。

中间的数太大。得上高精度。

用矩阵高速幂会超时,简单的DP就能解决时间的问题。

AC代码:

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <queue>
#include <map>
using namespace std;
map<char,int>mp;
int N,M,P;
struct Matrix
{
int mat[110][110];
int n;
Matrix(){}
Matrix(int _n)
{
n=_n;
for(int i = 0;i < n;i++)
for(int j = 0;j < n;j++)
mat[i][j] = 0;
}
};
struct Trie
{
int next[110][256],fail[110];
bool end[110];
int L,root;
int newnode()
{
for(int i = 0;i < 256;i++)
next[L][i] = -1;
end[L++] = false;
return L-1;
}
void init()
{
L = 0;
root = newnode();
}
void insert(char buf[])
{
int len = strlen(buf);
int now = root;
for(int i = 0;i < len;i++)
{
if(next[now][mp[buf[i]]] == -1)
next[now][mp[buf[i]]] = newnode();
now = next[now][mp[buf[i]]];
}
end[now] = true;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = 0;i < 256;i++)
if(next[root][i] == -1)
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while(!Q.empty())
{
int now = Q.front();
Q.pop();
if(end[fail[now]]==true)end[now]=true;
for(int i = 0;i < 256;i++)
if(next[now][i] == -1)
next[now][i] = next[fail[now]][i];
else
{
fail[next[now][i]] = next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
Matrix getMatrix()
{
Matrix res = Matrix(L);
for(int i = 0;i < L;i++)
for(int j = 0;j < N;j++)
if(end[next[i][j]]==false)
res.mat[i][next[i][j]]++;
return res;
}
void debug()
{
for(int i = 0;i < L;i++)
{
printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
for(int j = 0;j < 26;j++)
printf("%2d",next[i][j]);
printf("]\n");
}
} }; /*
* 高精度。支持乘法和加法
*/
struct BigInt
{
const static int mod = 10000;
const static int DLEN = 4;
int a[600],len;
BigInt()
{
memset(a,0,sizeof(a));
len = 1;
}
BigInt(int v)
{
memset(a,0,sizeof(a));
len = 0;
do
{
a[len++] = v%mod;
v /= mod;
}while(v);
}
BigInt(const char s[])
{
memset(a,0,sizeof(a));
int L = strlen(s);
len = L/DLEN;
if(L%DLEN)len++;
int index = 0;
for(int i = L-1;i >= 0;i -= DLEN)
{
int t = 0;
int k = i - DLEN + 1;
if(k < 0)k = 0;
for(int j = k;j <= i;j++)
t = t*10 + s[j] - '0';
a[index++] = t;
}
}
BigInt operator +(const BigInt &b)const
{
BigInt res;
res.len = max(len,b.len);
for(int i = 0;i <= res.len;i++)
res.a[i] = 0;
for(int i = 0;i < res.len;i++)
{
res.a[i] += ((i < len)? a[i]:0)+((i < b.len)? b.a[i]:0);
res.a[i+1] += res.a[i]/mod;
res.a[i] %= mod;
}
if(res.a[res.len] > 0)res.len++;
return res;
}
BigInt operator *(const BigInt &b)const
{
BigInt res;
for(int i = 0; i < len;i++)
{
int up = 0;
for(int j = 0;j < b.len;j++)
{
int temp = a[i]*b.a[j] + res.a[i+j] + up;
res.a[i+j] = temp%mod;
up = temp/mod;
}
if(up != 0)
res.a[i + b.len] = up;
}
res.len = len + b.len;
while(res.a[res.len - 1] == 0 &&res.len > 1)res.len--;
return res;
}
void output()
{
printf("%d",a[len-1]);
for(int i = len-2;i >=0 ;i--)
printf("%04d",a[i]);
printf("\n");
}
};
char buf[1010];
BigInt dp[2][110];
Trie ac;
int main()
{
// freopen("in.txt","r",stdin); while(scanf("%d%d%d",&N,&M,&P)==3)
{
gets(buf);
gets(buf);
mp.clear();
int len = strlen(buf);
for(int i = 0;i < len;i++)
mp[buf[i]]=i;
ac.init();
for(int i = 0;i < P;i++)
{
gets(buf);
ac.insert(buf);
}
ac.build();
Matrix a= ac.getMatrix(); int now = 0;
dp[now][0] = 1;
for(int i = 1;i < a.n;i++)
dp[now][i] = 0;
for(int i = 0;i < M;i++)
{
now^=1;
for(int j = 0;j < a.n;j++)
dp[now][j] = 0;
for(int j = 0;j < a.n;j++)
for(int k = 0;k < a.n;k++)
if(a.mat[j][k] > 0)
dp[now][k] = dp[now][k]+dp[now^1][j]*a.mat[j][k];
}
BigInt ans = 0;
for(int i = 0;i < a.n;i++)
ans = ans + dp[now][i];
ans.output();
}
return 0;
}

PS:代码风格来自bin神。

POJ 1625 Censored! (AC自己主动机 + 高精度 + DP)的更多相关文章

  1. ZOJ 3494 BCD Code (AC自己主动机 + 数位DP)

    题目链接:BCD Code 解析:n个病毒串.问给定区间上有多少个转换成BCD码后不包括病毒串的数. 很奇妙的题目. . 经典的 AC自己主动机 + 数位DP 的题目. 首先使用AC自己主动机,得到b ...

  2. [AC自己主动机+可能性dp] hdu 3689 Infinite monkey theorem

    意甲冠军: 给n快报,和m频率. 然后进入n字母出现的概率 然后给目标字符串str 然后问m概率倍的目标字符串是敲数量. 思维: AC自己主动机+可能性dp简单的问题. 首先建立trie图,然后就是状 ...

  3. POJ 3691 &amp; HDU 2457 DNA repair (AC自己主动机,DP)

    http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...

  4. HDU 2825 Wireless Password (AC自己主动机,DP)

    pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...

  5. POJ 1625 Censored!(AC自动机+DP+高精度)

    Censored! Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 6956   Accepted: 1887 Descrip ...

  6. POJ 1625 Censored! [AC自动机 高精度]

    Censored! Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 9793   Accepted: 2686 Descrip ...

  7. hdu 2825 Wireless Password(ac自己主动机&amp;dp)

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  8. poj 3691 DNA repair(AC自己主动机+dp)

    DNA repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5877   Accepted: 2760 Descri ...

  9. poj 1699 Best Sequence(AC自己主动机+如压力DP)

    id=1699" target="_blank" style="">题目链接:poj 1699 Best Sequence 题目大意:给定N个D ...

随机推荐

  1. Delphi最简化异步选择TCP服务器

    网上Delphi的Socket服务器优良代码,实在少见,索性写个简化的异步Socket服务器,虽然代码较少,但却该有的都有了,使用的是异步选择WSAAsyncSelect,减少了编写线程的繁琐.可能会 ...

  2. vue列表排序实现中的this问题

    最近在看vue框架的知识,然后其中有个例子中的this的写法让我很疑惑 <!DOCTYPE html> <html> <head> <meta charset ...

  3. Conv1D和Conv2D的区别

    我的答案是,在Conv2D输入通道为1的情况下,二者是没有区别或者说是可以相互转化的.首先,二者调用的最后的代码都是后端代码(以TensorFlow为例,在tensorflow_backend.py里 ...

  4. 记一次被面试的final问题

    ---- 前言 今天面试被问到了,我们都知道final修饰的东西是不可变的,那么是值不可变还是其地址不可变?一脸懵逼,回来查阅一番,总结一下 --- final与数据 在日常行为下,一般数据指的都是基 ...

  5. 性能测试培训day1

    测试本质: 1构造测试数据和期望结果 2执行 3验证 自动化测试: 写完代码,单元测试测代码逻辑,单元测试搞清楚代码逻辑就行了(白盒测试)先静态,运行前用工具扫描BUG例如(a==11写成a=11), ...

  6. scrapy快速入门

    1. 什么是scrapy? 其官网是这样简述的,“A Fast & Powerful Scraping &Crawling Framework ”,  并且其底层以twisted作为网 ...

  7. Quartz --Scheduler

  8. sscanf,sprintf

    sprintf函数 sprintf函数原型为 int sprintf(char str, const char format, ...).作用是格式化字符串,具体功能如下所示: 将数字变量转换为字符串 ...

  9. 百度富文本编辑器UEditor自定义上传图片接口

    如下图:  然后修改ueditor.all.js   

  10. 总结:常用的Linux系统监控命令(2)

    判断I/O瓶颈 mpstat命令 命令:mpstat -P ALL 1 1000 结果显示: 注意一下这里面的%iowait列,CPU等待I/O操作所花费的时间.这个值持续很高通常可能是I/O瓶颈所导 ...