POJ 1625 Censored!(AC自动机 + DP + 大数 + 拓展ASCII处理)题解
题意:给出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处理)题解相关推荐
- POJ - 1625 Censored!(AC自动机+dp+高精度运算)
题目链接:点击查看 题目大意:给出一个含有 n 个不同字符的字符集,接着规定所有单词的长度为 m ,再给出 k 个病毒串,问有多少个字符串中不含有病毒串 题目分析:这个题目和之前做过的DNA的那个题有 ...
- Censored! POJ - 1625(AC自动机 + dp +高精度模板)
题目链接 题目大意:给你一个字母表,给定一些敏感字符串,问长度为m且不含任意敏感字符串的串有多少个.(字符全部来自字母表) 思路:首先第一个坑点是输入的字符是unsigned char,可能出现负的A ...
- poj-1625 Censored![ac自动机+dp+高精度]
题目地址 先把病毒串丢进ac自动机里面. dp[i][j]表示长度为i的从trie图的根节点到j满足条件的串的数量. 因为答案很大,要用到高精度. 注意的是建图的时候,ed[u] |= ed[f[u] ...
- Censored! :ac自动机 + DP
分析 如果字符串的长度大一点可以用矩阵快速幂来做,因为数据范围比较小,可以用DP来代替 我们去枚举每一位在a自动机中的位置,再去枚举下一位的位置,判断是否打过标记,然后进行状态转移 需要注意的是,如果 ...
- POJ 1625 Censored ( Trie图 DP 高精度 )
题意 : 给出 n 个单词组成的字符集 以及 p 个非法串,问你用字符集里面的单词构造长度为 m 的单词的方案数有多少种? 分析 : 与 POJ 2778 非常相似的一道题目,如果没有做过就尝试去了解 ...
- 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂
[题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...
- uvalive4842(AC自动机+DP)
题意: 给出猴子打字时打某个字母的概率,猴子最多可以敲键盘m次,问得到的长度是m的单词包含模式串的概率. 思路: AC自动机+dp. 首先,我们用模式串构造一个AC自动机,用dp[i]][j]表示当前 ...
- HDU 2296 Ring AC自动机 + DP
题意:给你n个模式串,每个模式串有一个得分,让你构造出一个长度为N之内且分数最高的文本串;输出字典序列最小的. 解题思路: AC自动机 + DP , 不过要输出字典序列最小,多开一个 一个三维字符串 ...
- bzoj 1030: [JSOI2007]文本生成器(AC自动机+DP)
1030: [JSOI2007]文本生成器 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 5187 Solved: 2136 [Submit][St ...
- POJ 1625 Censored!(AC自动机-指针版+DP+大数)题解
题目:给你n个字母,p个模式串,要你写一个长度为m的串,要求这个串不能包含模式串,问你这样的串最多能写几个 思路:dp+AC自动机应该能看出来,万万没想到这题还要加大数...orz 状态转移方程dp[ ...
最新文章
- php替换时 css中的图片不显示不出来,URL重写:CSS,JS和图像未加载
- Fibonacci数列时间复杂度之美妙
- Microsoft.CSharp.CSharpCodeProvider
- ios开发循环网络请求_谈谈 iOS 网络层设计(SSJNetWork封装缓冲,log日志,自动取消网络请求)...
- Codeforces Beta Round #75 (Div. 1 Only) B. Queue 线段树。单点更新
- 大厂首发:2021年Java工作或更难找
- layui 表单动态添加、删除input框
- 哈希表数据结构_Java数据结构哈希表如何避免冲突
- 判断语句_如何学好C语言判断语句?攻略if语句是第一步
- object类型replace掉$、转换成float、运算
- 2种造成sqlserver自增列不连续的原因
- 二阶系统阶跃响应实验_二阶系统阶跃响应实验报告
- 马科维茨投资组合理论总结
- VR开发-罗德里格公式的研究
- BISTML-CRF项目源码
- 在线教育平台edx运营情况数据分析报告——SQLTableau
- 基于STM32智能家居控制系统软件设计及实现
- ground truth的含义
- 让一切都过去吧,高手挑战2过关方法
- 群辉安装python3,pip,环境变量配置
热门文章
- 6.7. exists, not exists
- Spark SQL 用户自定义函数UDF、用户自定义聚合函数UDAF 教程(Java踩坑教学版)
- “Hello World!“”团队第七周召开的第二次会议
- FlexboxLayout——Android弹性布局
- 系统优化设计方案3.20周一例会
- awk学习笔记(8) - 简单的正则匹配
- 关于ADO之AddNew,UPdate与Identity列
- 拜托!你真会用线程池吗?
- Nginx核心原理揭秘:Nginx为什么高效?
- 推荐几个我珍藏的公众号~超级无敌!