BZOJ 2553: [BeiJing2011]禁忌【ACAM + 期望dp + 矩快优化
2016-12-04 10:52
393 查看
……反正瞎瘠薄搞搞,都是显然的
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define MAXN 80
using namespace std; int n,m,ji;
struct Matrix{
long double d[MAXN][MAXN];
int x,y;
Matrix():x(0),y(0){memset(d,0,sizeof d);}
Matrix(int w):x(w),y(w){
memset(d,0,sizeof d);
for(int i=0;i<w;++i) d[i][i] = 1;
}
Matrix(int x,int y):x(x),y(y){memset(d,0,sizeof d);}
Matrix operator * (const Matrix ano) {
Matrix RTN(x,ano.y);
for(register int i=0;i<x;++i)
for(register int j=0;j<y;++j)
for(register int k=0;k<ano.y;++k)
RTN.d[i][k] += d[i][j] * ano.d[j][k];
return RTN;
}
inline Matrix pow(int c){
Matrix TMP = *this , RTN(x);
for(;c;c>>=1,TMP=TMP*TMP)
if(c&1)
RTN = RTN * TMP;
return RTN;
}
void write(){
puts("");
for(register int i=0;i<x;++i)
for(register int j=0;j<y;++j)
printf("%.0Lf%c",d[i][j],j==y-1?'\n':' ');
puts("");
}
}INIT,TRANS;
long double f[MAXN][MAXN];
long double ans = 0;
long double p;
struct ACAM{
int son[MAXN][26];
int cnt_node,root;
int fail[MAXN];
int tag[MAXN];
inline void init(){
root = cnt_node = 1;
}
char s[20];
inline void insert(int now){
scanf("%s",s);
for(char *i = s;*i;++i){
int x = (*i) - 'a';
if ( !son[now][x] ) son[now][x] = ++cnt_node;
now = son[now][x];
}
tag[now] = 1;
}
int que[MAXN],head,tail;
inline void bfs(int now){
head = tail = 1;
que[0] = now;
for(register int x=0;x<ji;++x)
if(son[now][x]) fail[ son[now][x] ] = now , que[tail++] = son[now][x];
else son[now][x] = now;
while(head^tail){
now = que[head++];
for(register int x=0;x<ji;++x)
if(son[now][x])
fail[ son[now][x] ] = son[ fail[now] ][x] ,
que[tail++] = son[now][x] ,
tag[ son[now][x] ] |= tag[fail[son[now][x]]];
else son[now][x] = son[ fail[now] ][x];
}
}
inline void DP(int len){
++cnt_node;
INIT = Matrix(cnt_node,1);
INIT.d[1][0] = 1;
TRANS = Matrix(cnt_node,cnt_node);
for(register int i=1;i<cnt_node;++i)
for(register int x=0;x<ji;++x){
int aim = son[i][x];
if(!tag[aim]) TRANS.d[aim][i] += p;
else{
TRANS.d[1][i] += p;
TRANS.d[0][i] += p;
}
}
TRANS.d[0][0] = 1;
INIT = TRANS.pow(len) * INIT;
printf("%.6Lf",INIT.d[0][0]);
// f[0][1] = 1;
// for(int i=0;i<len;++i){
// for(int j=0;j<tail;++j){
// int now = que[j];
// for(int k = 0;k<ji;++k){
// if(tag[son[now][k]])
// ans += f[i][now]*p , f[i+1][root] += f[i][now]*p;
// else f[i+1][son[now][k]] += f[i][now]*p;
// }
// }
// }
// printf("%.6Lf",ans);
}
}YJQ;
int main(){
YJQ.init();
scanf("%d%d%d",&n,&m,&ji);
p = (double)1/ji;
for(register int i=1;i<=n;++i) YJQ.insert(YJQ.root);
YJQ.bfs(YJQ.root);
YJQ.DP(m);
return 0;
}
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define MAXN 80
using namespace std; int n,m,ji;
struct Matrix{
long double d[MAXN][MAXN];
int x,y;
Matrix():x(0),y(0){memset(d,0,sizeof d);}
Matrix(int w):x(w),y(w){
memset(d,0,sizeof d);
for(int i=0;i<w;++i) d[i][i] = 1;
}
Matrix(int x,int y):x(x),y(y){memset(d,0,sizeof d);}
Matrix operator * (const Matrix ano) {
Matrix RTN(x,ano.y);
for(register int i=0;i<x;++i)
for(register int j=0;j<y;++j)
for(register int k=0;k<ano.y;++k)
RTN.d[i][k] += d[i][j] * ano.d[j][k];
return RTN;
}
inline Matrix pow(int c){
Matrix TMP = *this , RTN(x);
for(;c;c>>=1,TMP=TMP*TMP)
if(c&1)
RTN = RTN * TMP;
return RTN;
}
void write(){
puts("");
for(register int i=0;i<x;++i)
for(register int j=0;j<y;++j)
printf("%.0Lf%c",d[i][j],j==y-1?'\n':' ');
puts("");
}
}INIT,TRANS;
long double f[MAXN][MAXN];
long double ans = 0;
long double p;
struct ACAM{
int son[MAXN][26];
int cnt_node,root;
int fail[MAXN];
int tag[MAXN];
inline void init(){
root = cnt_node = 1;
}
char s[20];
inline void insert(int now){
scanf("%s",s);
for(char *i = s;*i;++i){
int x = (*i) - 'a';
if ( !son[now][x] ) son[now][x] = ++cnt_node;
now = son[now][x];
}
tag[now] = 1;
}
int que[MAXN],head,tail;
inline void bfs(int now){
head = tail = 1;
que[0] = now;
for(register int x=0;x<ji;++x)
if(son[now][x]) fail[ son[now][x] ] = now , que[tail++] = son[now][x];
else son[now][x] = now;
while(head^tail){
now = que[head++];
for(register int x=0;x<ji;++x)
if(son[now][x])
fail[ son[now][x] ] = son[ fail[now] ][x] ,
que[tail++] = son[now][x] ,
tag[ son[now][x] ] |= tag[fail[son[now][x]]];
else son[now][x] = son[ fail[now] ][x];
}
}
inline void DP(int len){
++cnt_node;
INIT = Matrix(cnt_node,1);
INIT.d[1][0] = 1;
TRANS = Matrix(cnt_node,cnt_node);
for(register int i=1;i<cnt_node;++i)
for(register int x=0;x<ji;++x){
int aim = son[i][x];
if(!tag[aim]) TRANS.d[aim][i] += p;
else{
TRANS.d[1][i] += p;
TRANS.d[0][i] += p;
}
}
TRANS.d[0][0] = 1;
INIT = TRANS.pow(len) * INIT;
printf("%.6Lf",INIT.d[0][0]);
// f[0][1] = 1;
// for(int i=0;i<len;++i){
// for(int j=0;j<tail;++j){
// int now = que[j];
// for(int k = 0;k<ji;++k){
// if(tag[son[now][k]])
// ans += f[i][now]*p , f[i+1][root] += f[i][now]*p;
// else f[i+1][son[now][k]] += f[i][now]*p;
// }
// }
// }
// printf("%.6Lf",ans);
}
}YJQ;
int main(){
YJQ.init();
scanf("%d%d%d",&n,&m,&ji);
p = (double)1/ji;
for(register int i=1;i<=n;++i) YJQ.insert(YJQ.root);
YJQ.bfs(YJQ.root);
YJQ.DP(m);
return 0;
}
相关文章推荐
- BZOJ2553 [BeiJing2011]禁忌 【AC自动机 + dp + 矩乘优化】
- 【BZOJ 2553】[BeiJing2011]禁忌 AC自动机+期望概率dp
- 【BZOJ2553】[BeiJing2011]禁忌 AC自动机+期望DP+矩阵乘法
- [AC自动机 矩阵快速幂 期望] BZOJ 2553 [BeiJing2011]禁忌
- BZOJ 2553: [BeiJing2011]禁忌(AC自动机+期望DP+矩阵快速幂)
- BZOJ 2553 BeiJing2011 禁忌 AC自动机+矩阵乘法
- bzoj 2553: [BeiJing2011]禁忌 AC自动机+矩阵乘法+期望
- bzoj 2553: [BeiJing2011]禁忌 AC自动机+矩阵乘法
- Bzoj2553 [BeiJing2011]禁忌
- BZOJ 2553: [BeiJing2011]禁忌
- [BZOJ2553] [BeiJing2011]禁忌-AC自动机-概率
- 【 bzoj 2553 】 [BeiJing2011]禁忌 - AC自动机+矩阵乘法
- BZOJ2553:[BeiJing2011]禁忌 AC自动机+矩阵快速幂
- [bzoj2553][BeiJing2011]禁忌
- bzoj2553【beijing2011】禁忌
- BZOJ 2553 [BeiJing2011]禁忌
- 【BZOJ2553】【BeiJing2011】禁忌 AC自动机 矩阵乘法 动态规划
- 【bzoj2553】[BeiJing2011]禁忌
- 【BZOJ】2553: [BeiJing2011]禁忌 AC自动机+期望+矩阵快速幂
- BZOJ2553: [BeiJing2011]禁忌 AC自动机 期望DP 矩阵