题意:给出n个字符,p个病毒串,要你求出长度为m的不包含病毒串的主串的个数

思路:不给取模最恶劣情况$50^{50}$,所以用高精度板子。因为m比较小,可以直接用DP写。

因为给你的串的字符包含拓展ASCII码(128~256),由于编译器的原因,char的读入范围在-128~127或者0~255之间不确定,所以你读一个拓展ASCII码的字符后可能是负的,那么你处理的时候要注意加130。或者你直接用map映射。或者用unsigned char。

代码:

#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100 + 5;
const int M = 50 + 5;
const ull seed = 131;
const double INF = 1e20;
const int MOD = 100000;
int n, m, p;
int tol;
int reflect[600];
struct BigInt{const static int mod = 10000;int a[50], len;BigInt(){memset(a, 0, sizeof(a));len = 1;}void set(int v){memset(a, 0, sizeof(a));len = 0;do{a[len++] = v % mod;v /= mod;}while(v);}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");}
};
BigInt dp[55][maxn];
struct Aho{struct state{int next[51];int fail, cnt;}node[maxn];int size;queue<int> q;void init(){size = 0;newtrie();while(!q.empty()) q.pop();}int newtrie(){memset(node[size].next, 0, sizeof(node[size].next));node[size].cnt = node[size].fail = 0;return size++;}void insert(char *s){int len = strlen(s);int now = 0;for(int i = 0; i < len; i++){int c = reflect[int(s[i]) + 130];if(node[now].next[c] == 0){node[now].next[c] = newtrie();}now = node[now].next[c];}node[now].cnt = 1;}void build(){node[0].fail = -1;q.push(0);while(!q.empty()){int u = q.front();q.pop();if(node[node[u].fail].cnt && u) node[u].cnt = 1;for(int i = 0; i < 51; i++){if(!node[u].next[i]){if(u == 0)node[u].next[i] = 0;elsenode[u].next[i] = node[node[u].fail].next[i];}else{if(u == 0) node[node[u].next[i]].fail = 0;else{int v = node[u].fail;while(v != -1){if(node[v].next[i]){node[node[u].next[i]].fail = node[v].next[i];break;}v = node[v].fail;}if(v == -1) node[node[u].next[i]].fail = 0;}q.push(node[u].next[i]);}}}}void query(){BigInt one;one.set(1);for(int i = 0; i <= m; i++){for(int j = 0; j < size; j++){dp[i][j].set(0);}}for(int i = 0; i < tol; i++){if(node[node[0].next[i]].cnt == 0){dp[1][node[0].next[i]] = dp[1][node[0].next[i]] + one;}}for(int i = 1; i <= m; i++){for(int j = 0; j < size; j++){for(int k = 0; k < tol; k++){if(node[node[j].next[k]].cnt == 0){dp[i + 1][node[j].next[k]] = dp[i + 1][node[j].next[k]] + dp[i][j];}}}}BigInt ans;ans.set(0);for(int i = 0; i < size; i++){if(node[i].cnt == 0){ans = ans + dp[m][i];}}ans.output();}}ac;
char s[100];
int main(){while(~scanf("%d%d%d", &n, &m, &p)){scanf("%s", s);tol = 0;for(int i = 0; i < n; i++){reflect[int(s[i]) + 130] = tol++;}ac.init();while(p--){scanf("%s", s);ac.insert(s);}ac.build();ac.query();}return 0;
}

#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100 + 5;
const int M = 50 + 5;
const ull seed = 131;
const double INF = 1e20;
const int MOD = 100000;
int n, m, p;
int tol;
map<char, int> reflect;
struct BigInt{const static int mod = 10000;int a[50], len;BigInt(){memset(a, 0, sizeof(a));len = 1;}void set(int v){memset(a, 0, sizeof(a));len = 0;do{a[len++] = v % mod;v /= mod;}while(v);}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");}
};
BigInt dp[55][maxn];
struct Aho{struct state{int next[51];int fail, cnt;}node[maxn];int size;queue<int> q;void init(){size = 0;newtrie();while(!q.empty()) q.pop();}int newtrie(){memset(node[size].next, 0, sizeof(node[size].next));node[size].cnt = node[size].fail = 0;return size++;}void insert(char *s){int len = strlen(s);int now = 0;for(int i = 0; i < len; i++){int c = reflect[s[i]];if(node[now].next[c] == 0){node[now].next[c] = newtrie();}now = node[now].next[c];}node[now].cnt = 1;}void build(){node[0].fail = -1;q.push(0);while(!q.empty()){int u = q.front();q.pop();if(node[node[u].fail].cnt && u) node[u].cnt = 1;for(int i = 0; i < 51; i++){if(!node[u].next[i]){if(u == 0)node[u].next[i] = 0;elsenode[u].next[i] = node[node[u].fail].next[i];}else{if(u == 0) node[node[u].next[i]].fail = 0;else{int v = node[u].fail;while(v != -1){if(node[v].next[i]){node[node[u].next[i]].fail = node[v].next[i];break;}v = node[v].fail;}if(v == -1) node[node[u].next[i]].fail = 0;}q.push(node[u].next[i]);}}}}void query(){BigInt one;one.set(1);for(int i = 0; i <= m; i++){for(int j = 0; j < size; j++){dp[i][j].set(0);}}for(int i = 0; i < tol; i++){if(node[node[0].next[i]].cnt == 0){dp[1][node[0].next[i]] = dp[1][node[0].next[i]] + one;}}for(int i = 1; i <= m; i++){for(int j = 0; j < size; j++){for(int k = 0; k < tol; k++){if(node[node[j].next[k]].cnt == 0){dp[i + 1][node[j].next[k]] = dp[i + 1][node[j].next[k]] + dp[i][j];}}}}BigInt ans;ans.set(0);for(int i = 0; i < size; i++){if(node[i].cnt == 0){ans = ans + dp[m][i];}}ans.output();}}ac;
char s[100];
int main(){while(~scanf("%d%d%d", &n, &m, &p)){scanf("%s", s);tol = 0;for(int i = 0; i < n; i++){reflect[s[i]] = tol++;}ac.init();while(p--){scanf("%s", s);ac.insert(s);}ac.build();ac.query();}return 0;
}

转载于:https://www.cnblogs.com/KirinSB/p/11185424.html

POJ 1625 Censored!(AC自动机 + DP + 大数 + 拓展ASCII处理)题解相关推荐

  1. POJ - 1625 Censored!(AC自动机+dp+高精度运算)

    题目链接:点击查看 题目大意:给出一个含有 n 个不同字符的字符集,接着规定所有单词的长度为 m ,再给出 k 个病毒串,问有多少个字符串中不含有病毒串 题目分析:这个题目和之前做过的DNA的那个题有 ...

  2. Censored! POJ - 1625(AC自动机 + dp +高精度模板)

    题目链接 题目大意:给你一个字母表,给定一些敏感字符串,问长度为m且不含任意敏感字符串的串有多少个.(字符全部来自字母表) 思路:首先第一个坑点是输入的字符是unsigned char,可能出现负的A ...

  3. poj-1625 Censored![ac自动机+dp+高精度]

    题目地址 先把病毒串丢进ac自动机里面. dp[i][j]表示长度为i的从trie图的根节点到j满足条件的串的数量. 因为答案很大,要用到高精度. 注意的是建图的时候,ed[u] |= ed[f[u] ...

  4. Censored! :ac自动机 + DP

    分析 如果字符串的长度大一点可以用矩阵快速幂来做,因为数据范围比较小,可以用DP来代替 我们去枚举每一位在a自动机中的位置,再去枚举下一位的位置,判断是否打过标记,然后进行状态转移 需要注意的是,如果 ...

  5. POJ 1625 Censored ( Trie图 DP 高精度 )

    题意 : 给出 n 个单词组成的字符集 以及 p 个非法串,问你用字符集里面的单词构造长度为 m 的单词的方案数有多少种? 分析 : 与 POJ 2778 非常相似的一道题目,如果没有做过就尝试去了解 ...

  6. 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂

    [题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...

  7. uvalive4842(AC自动机+DP)

    题意: 给出猴子打字时打某个字母的概率,猴子最多可以敲键盘m次,问得到的长度是m的单词包含模式串的概率. 思路: AC自动机+dp. 首先,我们用模式串构造一个AC自动机,用dp[i]][j]表示当前 ...

  8. HDU 2296 Ring AC自动机 + DP

    题意:给你n个模式串,每个模式串有一个得分,让你构造出一个长度为N之内且分数最高的文本串;输出字典序列最小的. 解题思路:  AC自动机 + DP , 不过要输出字典序列最小,多开一个 一个三维字符串 ...

  9. bzoj 1030: [JSOI2007]文本生成器(AC自动机+DP)

    1030: [JSOI2007]文本生成器 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 5187  Solved: 2136 [Submit][St ...

  10. POJ 1625 Censored!(AC自动机-指针版+DP+大数)题解

    题目:给你n个字母,p个模式串,要你写一个长度为m的串,要求这个串不能包含模式串,问你这样的串最多能写几个 思路:dp+AC自动机应该能看出来,万万没想到这题还要加大数...orz 状态转移方程dp[ ...

最新文章

  1. php替换时 css中的图片不显示不出来,URL重写:CSS,JS和图像未加载
  2. Fibonacci数列时间复杂度之美妙
  3. Microsoft.CSharp.CSharpCodeProvider
  4. ios开发循环网络请求_谈谈 iOS 网络层设计(SSJNetWork封装缓冲,log日志,自动取消网络请求)...
  5. Codeforces Beta Round #75 (Div. 1 Only) B. Queue 线段树。单点更新
  6. 大厂首发:2021年Java工作或更难找
  7. layui 表单动态添加、删除input框
  8. 哈希表数据结构_Java数据结构哈希表如何避免冲突
  9. 判断语句_如何学好C语言判断语句?攻略if语句是第一步
  10. object类型replace掉$、转换成float、运算
  11. 2种造成sqlserver自增列不连续的原因
  12. 二阶系统阶跃响应实验_二阶系统阶跃响应实验报告
  13. 马科维茨投资组合理论总结
  14. VR开发-罗德里格公式的研究
  15. BISTML-CRF项目源码
  16. 在线教育平台edx运营情况数据分析报告——SQLTableau
  17. 基于STM32智能家居控制系统软件设计及实现
  18. ground truth的含义
  19. 让一切都过去吧,高手挑战2过关方法
  20. 群辉安装python3,pip,环境变量配置

热门文章

  1. 6.7. exists, not exists
  2. Spark SQL 用户自定义函数UDF、用户自定义聚合函数UDAF 教程(Java踩坑教学版)
  3. “Hello World!“”团队第七周召开的第二次会议
  4. FlexboxLayout——Android弹性布局
  5. 系统优化设计方案3.20周一例会
  6. awk学习笔记(8) - 简单的正则匹配
  7. 关于ADO之AddNew,UPdate与Identity列
  8. 拜托!你真会用线程池吗?
  9. Nginx核心原理揭秘:Nginx为什么高效?
  10. 推荐几个我珍藏的公众号~超级无敌!