Censored! POJ - 1625 AC自动机+大数DP
题意:
给出一n种字符的字典,有p个禁用的单词,
问能组成多少个不同的长度为m的合法字符串。(m<=50)
题解:
是不是个我们之前做的题目非常非常像,题意都一样。
直接将上次写的AC自动机+矩阵快速幂的代码交上去。
然后突然发现没有取模,好像直接炸了。即便只有50,但是方案数还是爆__int128了
处理不了,这题还是必须用大数的。
p<=10 我们可以考虑状压实现。
这题还是和之前的题目有点关系的,需要求出可达矩阵,然后根据这个去DP
dp[i][j] 表示第 i 步 在AC自动机 j 这个节点 的方案数目,
然后第 i 步只跟 第 i - 1步的状态有关,然后可以滚动掉这一维。
不用试不滚动的了,会mle的。 别问我怎么知道的!!!!
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <time.h>
#include <cstring>
#include <iostream>
#include <algorithm> #define pi acos(-1.0)
#define eps 1e-9
#define fi first
#define se second
#define rtl rt<<1
#define rtr rt<<1|1
#define bug printf("******\n")
#define mem(a, b) memset(a,b,sizeof(a))
#define name2str(x) #x
#define fuck(x) cout<<#x" = "<<x<<endl
#define sf(n) scanf("%d", &n)
#define sff(a, b) scanf("%d %d", &a, &b)
#define sfff(a, b, c) scanf("%d %d %d", &a, &b, &c)
#define sffff(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
#define pf printf
#define FIN freopen("../date.txt","r",stdin)
#define gcd(a, b) __gcd(a,b)
#define lowbit(x) x&-x
#define IO iOS::sync_with_stdio(false) using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int maxn = 1e6 + ;
const int maxm = 8e6 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ; struct Matrix {
int mat[][], n; Matrix() {} Matrix(int _n) {
n = _n;
for (int i = ; i < n; i++)
for (int j = ; j < n; j++)
mat[i][j] = ;
} Matrix operator*(const Matrix &b) const {
Matrix ret = Matrix(n);
for (int i = ; i < n; i++)
for (int j = ; j < n; j++)
for (int k = ; k < n; k++) {
int tmp = (long long) mat[i][k] * b.mat[k][j] % mod;
ret.mat[i][j] = (ret.mat[i][j] + tmp) % mod;
}
return ret;
}
}; char buf[];
int n, m, p;
map<char, int> mp; struct Aho_Corasick {
int next[][], fail[], End[];
int root, cnt; int newnode() {
for (int i = ; i < ; i++) next[cnt][i] = -;
End[cnt++] = ;
return cnt - ;
} void init() {
cnt = ;
root = newnode();
} void insert(char buf[]) {
int len = strlen(buf);
int now = root;
for (int i = ; i < len; i++) {
if (next[now][mp[buf[i]]] == -) next[now][mp[buf[i]]] = newnode();
now = next[now][mp[buf[i]]];
}
End[now]++;
} void build() {
queue<int> Q;
fail[root] = root;
for (int i = ; i < ; i++)
if (next[root][i] == -) 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]]) End[now] = ;
for (int i = ; i < ; i++)
if (next[now][i] == -) next[now][i] = next[fail[now]][i];
else {
fail[next[now][i]] = next[fail[now]][i];
Q.push(next[now][i]);
}
}
} Matrix get_Matrix() {
Matrix ret = Matrix(cnt);
for (int i = ; i < cnt; ++i) {
for (int j = ; j < n; ++j) {
if (!End[next[i][j]]) ret.mat[i][next[i][j]]++;
}
}
return ret;
} void debug() {
for (int i = ; i < cnt; i++) {
printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]);
for (int j = ; j < ; j++) printf("%2d", next[i][j]);
printf("]\n");
}
}
} ac; const int MAXL = ;
const int MAXN = ;
const int DLEN = ; class Big {
public:
int a[], len; Big(const int b = ) {
int c, d = b;
len = ;
memset(a, , sizeof(a));
while (d > MAXN) {
c = d - (d / (MAXN + )) * (MAXN + );
d = d / (MAXN + );
a[len++] = c;
}
a[len++] = d;
} Big(const char *s) {
int t, k, index, L;
memset(a, , sizeof(a));
L = strlen(s);
len = L / DLEN;
if (L % DLEN) len++;
index = ;
for (int i = L - ; i >= ; i -= DLEN) {
t = ;
k = i - DLEN + ;
if (k < ) k = ;
for (int j = k; j <= i; j++) t = t * + s[j] - '';
a[index++] = t;
}
} Big operator/(const LL &b) const {
Big ret;
LL down = ;
for (int i = len - ; i >= ; i--) {
ret.a[i] = (a[i] + down * (MAXN + )) / b;
down = a[i] + down * (MAXN + ) - ret.a[i] * b;
}
ret.len = len;
while (ret.a[ret.len - ] == && ret.len > ) ret.len--;
return ret;
} bool operator>(const Big &T) const {
int ln;
if (len > T.len) return true;
else if (len == T.len) {
ln = len - ;
while (a[ln] == T.a[ln] && ln >= ) ln--;
if (ln >= && a[ln] > T.a[ln]) return true;
else return false;
} else return false;
} Big operator+(const Big &T) const {
Big t(*this);
int big = T.len > len ? T.len : len;
for (int i = ; i < big; i++) {
t.a[i] += T.a[i];
if (t.a[i] > MAXN) {
t.a[i + ]++;
t.a[i] -= MAXN + ;
}
}
if (t.a[big] != ) t.len = big + ;
else t.len = big;
return t;
} Big operator-(const Big &T) const {
int big;
bool flag;
Big t1, t2;
if (*this > T) {
t1 = *this;
t2 = T;
flag = ;
} else {
t1 = T;
t2 = *this;
flag = ;
}
big = t1.len;
for (int i = ; i < big; i++) {
if (t1.a[i] < t2.a[i]) {
int j = i + ;
while (t1.a[j] == ) j++;
t1.a[j--]--;
while (j > i) t1.a[j--] += MAXN;
t1.a[i] += MAXN + - t2.a[i];
} else t1.a[i] -= t2.a[i];
}
t1.len = big;
while (t1.a[t1.len - ] == && t1.len > ) {
t1.len--;
big--;
}
if (flag) t1.a[big - ] = - t1.a[big - ];
return t1;
} LL operator%(const int &b) const {
LL d = ;
for (int i = len - ; i >= ; i--) d = ((d * (MAXN + )) % b + a[i]) % b;
return d;
} Big operator*(const Big &T) const {
Big ret;
int i, j, up, temp, temp1;
for (i = ; i < len; i++) {
up = ;
for (j = ; j < T.len; j++) {
temp = a[i] * T.a[j] + ret.a[i + j] + up;
if (temp > MAXN) {
temp1 = temp - temp / (MAXN + ) * (MAXN + );
up = temp / (MAXN + );
ret.a[i + j] = temp1;
} else {
up = ;
ret.a[i + j] = temp;
}
}
if (up != ) ret.a[i + j] = up;
}
ret.len = i + j;
while (ret.a[ret.len - ] == && ret.len > ) ret.len--;
return ret;
} void print() {
printf("%d", a[len - ]);
for (int i = len - ; i >= ; i--) printf("%04d", a[i]);
}
}; Big dp[][]; int main() {
//FIN;
while (~scanf("%d%d%d", &n, &m, &p)) {
mp.clear();
scanf("%s", buf);
int len = strlen(buf);
for (int i = ; i < len; ++i) mp[buf[i]] = i;
ac.init();
for (int i = ; i < p; ++i) {
scanf("%s", buf);
ac.insert(buf);
}
ac.build();
Matrix mat = ac.get_Matrix();
// for (int i = 0; i < mat.n; ++i) {
// for (int j = 0; j < mat.n; ++j) {
// printf("%d ",mat.mat[i][j]);
// }
// printf("\n");
// }
int now=;
dp[now][] = ;
for (int i = ; i < mat.n; ++i) dp[now][i] = ;
for (int i = ; i <= m; ++i) {
now^=;
for (int j = ; j < mat.n; ++j) dp[now][j]=;
for (int j = ; j < mat.n; ++j) {
for (int k = ; k < mat.n; ++k) {
if (mat.mat[j][k]) dp[now][k] = dp[now][k] + dp[now^][j] * mat.mat[j][k];
}
}
}
Big ans = ;
for (int i = ; i < mat.n; ++i) ans = ans + dp[now][i];
ans.print();
printf("\n");
}
return ;
}
Censored! POJ - 1625 AC自动机+大数DP的更多相关文章
- Censored! - POJ 1625(ac自动机+简单dp+高精度运算)
题目大意:首先给一个字符集合,这个集合有N个字符,然后需要一个长度为M的句子,但是据子里面不能包含的串有P个,每个串里面的字符都是有字符集和里面的字符构成的,现在想知道最多能构造多少个不重复的句子. ...
- 【HDU3530】 [Sdoi2014]数数 (AC自动机+数位DP)
3530: [Sdoi2014]数数 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 682 Solved: 364 Description 我们称一 ...
- 关于AC自动机和DP的联系
首先是描述个大概.不说一些特殊的DP 或者借用矩阵来状态转移 (这些本质都是一样的). 只讲AC自动机和DP的关系(个人理解). AC自动机 又可以叫做状态机. 我一开始的认为.AC 自动机提供了一些 ...
- 【bzoj3530】[Sdoi2014]数数 AC自动机+数位dp
题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...
- BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)
题目大意:略 裸的AC自动机+数位DP吧... 定义f[i][x][0/1]表示已经匹配到了第i位,当前位置是x,0表示没到上限,1到上限,此时数是数量 然而会出现虚拟前导零,即前几位没有数字的情况, ...
- POJ 3691 (AC自动机+状态压缩DP)
题目链接: http://poj.org/problem?id=3691 题目大意:给定N个致病DNA片段以及一个最终DNA片段.问最终DNA片段最少修改多少个字符,使得不包含任一致病DNA. 解题 ...
- POJ2778&HDU2243&POJ1625(AC自动机+矩阵/DP)
POJ2778 题意:只有四种字符的字符串(A, C, T and G),有M中字符串不能出现,为长度为n的字符串可以有多少种. 题解:在字符串上有L中状态,所以就有L*A(字符个数)中状态转移.这里 ...
- POJ 2778 (AC自动机+矩阵乘法)
POJ 2778 DNA Sequence Problem : 给m个只含有(A,G,C,T)的模式串(m <= 10, len <=10), 询问所有长度为n的只含有(A,G,C,T)的 ...
- 【POJ2778】DNA Sequence(AC自动机,DP)
题意: 生物课上我们学到,DNA序列中只有A, C, T和G四种片段. 经科学发现,DNA序列中,包含某些片段会产生不好的基因,如片段"ATC"是不好片段,则"AGATC ...
随机推荐
- Delphi ADOQuery的属性 locktype、CursorLocation 、Filter、CursorType、CancelBatch 和 UpdateBatch
以下数据,部分来自网络的收集,部分为自己测试后的原创整理,希望对你有帮助,更新会注明日期. 1.locktype 指定用户打开数据集时对数据集的锁定级别: ltUnspecified 未指定锁定 ...
- Django使用步骤
pip install django django-admin startproject mysite tree django-admin startapp mysite_user django-ad ...
- 好用的日期控件jeDate
最近做公司后台系统关于仓库的一些东西,需要根据时间范围来导出一些数据,我们使用的后台框架是基于bs的,bs也有时间控件:bootstrap-datepicker是只能选择日期的, daterangep ...
- Delphi 2010下使用sqlitesimpledelphi连接SQLite数据库及中文乱码问题的解决
应女朋友的要求,要写一款销售管理的软件.用于管理服装店每天的销售记录,已及管理服装店的客户,并对客户进行生日提醒 因为之前使用C#写过一款家庭管理软件,主要是自己用,所以使用了服务器型数据库MySQL ...
- 再学 GDI+文本输出文本样式
代码文件: unit Unit1; interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls ...
- Photon Server与Unity3D客户端的交互
Photon Server与Unity3D的交互分为3篇博文实现 (1)Photon Server的服务器端配置 (2)Photon Server的Unity3D客户端配置 (3)Photon Ser ...
- flutter 插件
flutter_spinkit loading动画
- DXP 快捷键
EC 复制 EY array paste TU: update
- PAT_A1102#Invert a Binary Tree
Source: PAT A1102 Invert a Binary Tree (25 分) Description: The following is from Max Howell @twitter ...
- VS新建工程或者新建项时 出现未定义标识符号
VS新建工程或者新建项时 出现未定义标识符号,编译之后不影响运行,但是看着很不舒服,影响效率. 解决办法:属性--->VC++目录-->包含目录-->编辑,将自己所用QT的inclu ...