poj 1625 (AC自动机好模版,大数好模版)
给n个字母,构成长度为m的串,总共有n^m种。给p个字符串,问n^m种字符串中不包含(不是子串)这p个字符串的个数。
将p个不能包含的字符串建立AC自动机,每个结点用val值来标记以当前节点为后缀的字符串是否包含非法字符串(p个字符串中的任何一个)。
状态转移方程:f(i, j) += f(i-1, k)
f(i, j)表示长度为i的字符串,结尾为字符j,方程j和k的关系可以从自动机中失配关系直接获得(j是k的后继结点)。
总之感觉是好东西,快存下来
大数模版:
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std; struct BigInteger{
int A[];
enum{MOD = };
BigInteger(){memset(A, , sizeof(A)); A[]=;}
void set(int x){memset(A, , sizeof(A)); A[]=; A[]=x;}
void print(){
printf("%d", A[A[]]);
for (int i=A[]-; i>; i--){
if (A[i]==){printf(""); continue;}
for (int k=; k*A[i]<MOD; k*=) printf("");
printf("%d", A[i]);
}
printf("\n");
}
int& operator [] (int p) {return A[p];}
const int& operator [] (int p) const {return A[p];}
BigInteger operator + (const BigInteger& B){
BigInteger C;
C[]=max(A[], B[]);
for (int i=; i<=C[]; i++)
C[i]+=A[i]+B[i], C[i+]+=C[i]/MOD, C[i]%=MOD;
if (C[C[]+] > ) C[]++;
return C;
}
BigInteger operator * (const BigInteger& B){
BigInteger C;
C[]=A[]+B[];
for (int i=; i<=A[]; i++)
for (int j=; j<=B[]; j++){
C[i+j-]+=A[i]*B[j], C[i+j]+=C[i+j-]/MOD, C[i+j-]%=MOD;
}
if (C[C[]] == ) C[]--;
return C;
}
};
int main() {
BigInteger a, b;
a.set(); b.set();
(a+b).print(); return ;
}
本题答案(内含AC自动机模版):
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
typedef unsigned char uchar; struct AC_Automata {
#define N 102
int ch[N][], val[N], last[N], f[N], sz;
void clear() { sz = ; memset(ch[], , sizeof(ch[])); } int hash[], M;
void set_hash(int n, uchar s[]) {
M = n; for (int i=; i<n; i++) hash[s[i]] = i;
}
void insert(uchar s[], int v) {
int u = ;
for (int i=; s[i]; i++) {
int c = hash[s[i]];
if (!ch[u][c]) {
memset(ch[sz], , sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v; //标记当前串为非法的
}
void build() {
queue<int> q;
f[] = ;
for (int c=; c<M; c++) {
int u = ch[][c];
if (u) { f[u] = last[u] = ; q.push(u); }
}
while (!q.empty()) {
int r = q.front(); q.pop();
for (int c=; c<M; c++) {
int u = ch[r][c];
val[r] = val[r] || val[f[r]]; //判断当前结点是否有非法后缀
if (!u) {
ch[r][c] = ch[f[r]][c];
continue;
}
q.push(u);
f[u] = ch[f[r]][c];
last[u] = val[f[u]] ? f[u] : last[f[u]];
}
}
}
} ac;
struct BigInteger{
int A[];
enum{MOD = };
BigInteger(){memset(A, , sizeof(A)); A[]=;}
void set(int x){memset(A, , sizeof(A)); A[]=; A[]=x;}
void print(){
printf("%d", A[A[]]);
for (int i=A[]-; i>; i--){
if (A[i]==){printf(""); continue;}
for (int k=; k*A[i]<MOD; k*=) printf("");
printf("%d", A[i]);
}
printf("\n");
}
int& operator [] (int p) {return A[p];}
const int& operator [] (int p) const {return A[p];}
BigInteger operator + (const BigInteger& B){
BigInteger C;
C[]=max(A[], B[]);
for (int i=; i<=C[]; i++)
C[i]+=A[i]+B[i], C[i+]+=C[i]/MOD, C[i]%=MOD;
if (C[C[]+] > ) C[]++;
return C;
}
BigInteger operator * (const BigInteger& B){
BigInteger C;
C[]=A[]+B[];
for (int i=; i<=A[]; i++)
for (int j=; j<=B[]; j++){
C[i+j-]+=A[i]*B[j], C[i+j]+=C[i+j-]/MOD, C[i+j-]%=MOD;
}
if (C[C[]] == ) C[]--;
return C;
}
};
int n, m, p;
uchar s[]; int main() { while (scanf("%d %d %d ", &n, &m, &p) == ) {
ac.clear();
cin >> s; ac.set_hash(n, s);
while (p--) {
cin >> s; ac.insert(s, );
}
ac.build(); BigInteger f[][];
f[][].set(); for (int i=; i<=m; i++)
for (int j=; j<ac.sz; j++)
for (int k=; k<n; k++) {
int u = ac.ch[j][k];
if (!ac.val[u]) f[i][u] = f[i][u] + f[i-][j];
}
BigInteger ans;
for (int i=; i<ac.sz; i++)
if (!ac.val[i]) ans = ans + f[m][i];
ans.print();
}
return ;
}
poj 1625 (AC自动机好模版,大数好模版)的更多相关文章
- Censored! POJ - 1625 AC自动机+大数DP
题意: 给出一n种字符的字典,有p个禁用的单词, 问能组成多少个不同的长度为m的合法字符串.(m<=50) 题解: 是不是个我们之前做的题目非常非常像,题意都一样. 直接将上次写的AC自动机+矩 ...
- Censored! - POJ 1625(ac自动机+简单dp+高精度运算)
题目大意:首先给一个字符集合,这个集合有N个字符,然后需要一个长度为M的句子,但是据子里面不能包含的串有P个,每个串里面的字符都是有字符集和里面的字符构成的,现在想知道最多能构造多少个不重复的句子. ...
- POJ 3691 (AC自动机+状态压缩DP)
题目链接: http://poj.org/problem?id=3691 题目大意:给定N个致病DNA片段以及一个最终DNA片段.问最终DNA片段最少修改多少个字符,使得不包含任一致病DNA. 解题 ...
- POJ 2778 (AC自动机+矩阵乘法)
POJ 2778 DNA Sequence Problem : 给m个只含有(A,G,C,T)的模式串(m <= 10, len <=10), 询问所有长度为n的只含有(A,G,C,T)的 ...
- POJ 2896 AC自动机 or 暴力
DESCRIPTION :大意是说.给你n个代表病毒的字符串.m个表示网站的字符串.让你计算有多少个网站被病毒感染了.被那些病毒感染了. 刚开始就想暴力.然而,忽略了条件:每个网站最多有三个病毒.于是 ...
- DNA Sequence POJ - 2778 AC自动机 && 矩阵快速幂
It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's very useful to ...
- poj 4052(ac自动机)
题意:自己百度吧!! 分析:就是通过它的fail指针来找出它的子串就行了,这题其实不难的.这好像还是金华邀请赛的题哦! 代码实现: #include<cstdio> #include< ...
- poj 2778 AC自动机+矩阵快速幂
题目链接:https://vjudge.net/problem/POJ-2778 题意:输入n和m表示n个病毒,和一个长为m的字符串,里面只可以有'A','C','G','T' 这四个字符,现在问这个 ...
- DNA Sequence POJ - 2778 AC 自动机 矩阵乘法
定义重载运算的时候一定要将矩阵初始化,因为这个调了一上午...... Code: #include<cstdio> #include<algorithm> #include&l ...
随机推荐
- 【BZOJ-1984】月下“毛景树” 树链剖分
1984: 月下“毛景树” Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1314 Solved: 416[Submit][Status][Discu ...
- document.body.scrollTop 各浏览器兼容性解决
document.compatMode:获取当前浏览器采用的渲染方式.主要是浏览器的模式,有两个:BackCompat,CSS1Compat.其中前者是怪异模式,后者是标准模式. IE默认是BackC ...
- Web Api如何传递POST请求
这里记录一次Web Api传递post请求的例子,由于使用了默认工程的例子,方法名的参数值标记头为FromBody的形式,如下图所示的调用: 调用方式: 那么如果要两个以上的参数如何去实现,这种方式是 ...
- Yii2 初体验
看着Yii1.1有那么多的不爽,又看着Yii2一天天成熟起来,于是凑一个小项目的原型阶段,试着用Yii2搞一搞. 随手写了一点体会,以一个Yii1的熟练工人看向Yii2的视角,简单一说吧.(将来随时可 ...
- [Python] Python 之 __new__() 方法与实例化
__new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在 Python 中存在于类里面的构造方法 __init__() 负责将类的实例化,而在 __init__() ...
- 在Main中定义student的结构体,进行年龄从大到小依次排序录入学生信息。(结构体的用法以及冒泡排序)
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using S ...
- 分子量 (Molar Mass,ACM/ICPC Seoul 2007,UVa 1586)
解题思路: 1.将分子量用double 数组记录下来 2.将字符串存储在字符数组中,从头向后扫描,一直记住“字母”,对下一个字符进行判断,是否是数字,如果是数字:用一个整数记录,本代码中用的sum,同 ...
- Jquery 表单操作
文本框,文本区域: 获取值: 1.$("#txt").attr("value"); 2. $("txt").val(); 单选按钮: 获取值 ...
- struts2 访问国际化资源 <s:text>作为属性
保留全局级国际化信息资源文件.并在message.properteis中增加一个带有参数的国际化信息. labela = labela in zh_CN labelb = labelb,{0} < ...
- java源代码分析----jvm.dll装载过程
简述众所周知java.exe是java class文件的执行程序,但实际上java.exe程序只是一个执行的外壳,它会装载jvm.dll(windows下,以下皆以windows平台为例,linux下 ...