题意:给一些字符串的集合S和整数n,求满足

  • 长度为n
  • 只含charset = {'A'、'T‘、'G'、'C'}包含的字符
  • 不包含S中任一字符串

的字符串的种类数。

思路:首先对S建立ac自动机,考虑向ac自动机中的每种状态后加charset中的字符,如果终态不为“接受状态”,也就是不与S中的任一字符串匹配,则将这次转移记为有效,方法数加1。这样可以建立状态之间的转移矩阵D,表示由一个状态接受1个字符后的方案数,D自乘n次,就得到了任一状态接受n个字符形成的不同字符串种类数,其中从“0”到“i”的方案都要加到答案里面。

另外,这题的模比较有意思,为100000,既不大也不小,或者说是个比较猥琐的数。对于100*100的矩阵,这样取模当然是吃不消的,方法是对每个点算完后一次性取模。时间由800ms→125ms。

  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#pragma comment(linker, "/STACK:10240000")
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; #define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define fillarray(a, b) memcpy(a, b, sizeof(a)) typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull; #ifndef ONLINE_JUDGE
namespace Debug {
void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
}
#endif // ONLINE_JUDGE template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);} const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const double EPS = 1e-14; /* -------------------------------------------------------------------------------- */ const int maxn = ;
const int mod = ; int N; struct Matrix {
ll a[maxn][maxn]; Matrix() {
for (int i = ; i < N; i ++) {
for (int j = ; j < N; j ++) {
a[i][j] = ;
}
}
} static Matrix unit() {
Matrix ans;
for (int i = ; i < N; i ++) ans.a[i][i] = ;
return ans;
} Matrix &operator * (const Matrix &that) const {
static Matrix ans;
for (int i = ; i < N; i ++) {
for (int j = ; j < N; j ++) {
ans.a[i][j] = ;
for (int k = ; k < N; k ++) {
ans.a[i][j] += a[i][k] * that.a[k][j];
}
ans.a[i][j] %= mod;
}
}
return ans;
} static Matrix power(Matrix a, int n) {
Matrix ans = unit(), buf = a;
while (n) {
if (n & ) ans = ans * buf;
buf = buf * buf;
n >>= ;
}
return ans;
}
}; struct AC_automaton {
const static int SZ = ;
int f[maxn], last[maxn];
bool val[maxn];
int ch[maxn][SZ];
int sz; int idx(char ch) {
if (ch == 'A') return ;
if (ch == 'T') return ;
if (ch == 'G') return ;
if (ch == 'C') return ; } void init() {
sz = ;
memset(ch[], , sizeof(ch[]));
} void insert(char s[]) {
int u = ;
for (int i = ; s[i]; i ++) {
int c = idx(s[i]);
if (!ch[u][c]) {
memset(ch[sz], , sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz ++;
}
u = ch[u][c];
}
val[u] = true;
} void build() {
queue<int> Q;
f[] = ;
for (int c = ; c < SZ; c ++) {
int u = ch[][c];
if (u) {
f[u] = ;
Q.push(u);
last[u] = ;
}
}
while (!Q.empty()) {
int r = Q.front(); Q.pop();
for (int c = ; c < SZ; c ++) {
int u = ch[r][c];
if (!u) {
ch[r][c] = ch[f[r]][c];
continue;
}
Q.push(u);
int v = f[r];
while (v && !ch[v][c]) v = f[v];
f[u] = ch[v][c];
last[u] = val[f[u]]? f[u] : last[f[u]];
}
}
} void solve(int m) {
N = sz;
Matrix ans;
//Debug::print(sz);
for (int i = ; i < sz; i ++) {
for (int j = ; j < ; j ++) {
if (!val[ch[i][j]] && !last[ch[i][j]]) {
ans.a[i][ch[i][j]] ++;
}
}
}
ans = Matrix::power(ans, m);
int rst = ;
for (int i = ; i < sz; i ++) {
rst = (rst + ans.a[][i]) % mod;
}
printf("%d\n", rst);
} }; AC_automaton ac; int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int n, m;
char s[];
while (cin >> n >> m) {
ac.init();
for (int i = ; i < n; i ++) {
scanf("%s", s);
ac.insert(s);
}
ac.build();
ac.solve(m);
}
return ;
}

[poj2778 DNA Sequence]AC自动机,矩阵快速幂的更多相关文章

  1. [poj2778]DNA Sequence(AC自动机+矩阵快速幂)

    题意:有m种DNA序列是有疾病的,问有多少种长度为n的DNA序列不包含任何一种有疾病的DNA序列.(仅含A,T,C,G四个字符) 解题关键:AC自动机,实际上就是一个状态转移图,注意能少取模就少取模, ...

  2. poj2778 DNA Sequence(AC自动机+矩阵快速幂)

    Description It's well known that DNA Sequence is a sequence only contains A, C, T and G, and it's ve ...

  3. poj 2778 DNA Sequence ac自动机+矩阵快速幂

    链接:http://poj.org/problem?id=2778 题意:给定不超过10串,每串长度不超过10的灾难基因:问在之后给定的长度不超过2e9的基因长度中不包含灾难基因的基因有多少中? DN ...

  4. poj2778DNA Sequence (AC自动机+矩阵快速幂)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud DNA Sequence Time Limit: 1000MS   Memory ...

  5. POJ2778 DNA Sequence(AC自动机 矩阵)

    先使用AC自动机求得状态转移关系,再建立矩阵,mat[i][j]表示一步可从i到j且i,j节点均非终止字符的方案数,则此矩阵的n次方表示n步从i,到j的方法数. #include<cstdio& ...

  6. POJ2778 DNA Sequence(AC自动机+矩阵快速幂)

    题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个. 感觉这题好神,看了好久的题解. 所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个 ...

  7. POJ 2778 DNA Sequence (ac自动机+矩阵快速幂)

    DNA Sequence Description It's well known that DNA Sequence is a sequence only contains A, C, T and G ...

  8. 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 ...

  9. POJ 2778 DNA Sequence(AC自动机 + 矩阵快速幂)题解

    题意:给出m个模式串,要求你构造长度为n(n <= 2000000000)的主串,主串不包含模式串,问这样的主串有几个 思路:因为要不包含模式串,显然又是ac自动机.因为n很大,所以用dp不太好 ...

  10. POJ2778(SummerTrainingDay10-B AC自动机+矩阵快速幂)

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17160   Accepted: 6616 Des ...

随机推荐

  1. E - Aladdin and the Flying Carpet

    It's said that Aladdin had to solve seven mysteries before getting the Magical Lamp which summons a ...

  2. python selenium模块 xpath定位

    ''' 附w3xpath语法地址 https://www.w3school.com.cn/xpath/xpath_syntax.asp 总结: 返回匹配到所有符合条件的第一个节点,对象是 <cl ...

  3. billu b0x2靶机渗透

    实战渗透靶机billu b0x2 攻击kali :192.168.41.147 靶机b0x2: 192.168.41.148 起手先nmap扫了一下 扫到了四个开放的端口,有ssh,http,rpcb ...

  4. 彻底解决Python编码问题

    1. 基本概念 字符集(Character set) 解释:文字和符合的总称 常见字符集: Unicode字符集 ASCII字符集(Unicode子集) GB2312字符集 编码方法(Encoding ...

  5. vue3开发饿了么商城2020年新版本

    带手机验证码登陆, 带全套购物车系统 带数据库 前后端分离开发 带定位用户功能 数据库代码为本地制作好了 带支付宝支付系统 带django开发服务器接口教程 地址:   https://www.dua ...

  6. PHP Callable强制指定回调类型的方法

    如果一个方法需要接受一个回调方法作为参数,我们可以这样写 <?php function dosth($callback){ call_user_func($callback); } functi ...

  7. Mac安装Nginx、Mysql、PHP、Redis

    安装xcode命令行工具的命令 xcode-select --install   安装homebrew: ruby -e "$(curl -fsSL https://raw.githubus ...

  8. 2019-2020-20199303《Linux内核原理与分析》第四周作业

    构造一个简单的Linux内核 Linux是一种开源电脑操作系统内核,它是一个用C语言写成.主要子系统: 1.系统调用接口 2.进程管理 3.内存管理 4.虚拟文件系统 qemu是一个开源模拟处理器,在 ...

  9. Json & pickle 数据序列化

    前提: 文本文件中只能写入字符串或ascii码格式的内容. info={'name':'zoe','age':18} f=open('test.txt','w') f.write(info) #在文本 ...

  10. ZLEXCOUNT key min max

    1 简介 ZLEXCOUNT 命令用于计算有序集合中指定成员之间的成员数量. 2 语法 2.1 完整示例 zlexcount zset [member1 [member5 2.2 说明 指令 是否必须 ...