[AC自动机+期望DP] 玲珑ACM 1025 - Magic boy Bi Luo with his excited string problem
来源:互联网 发布:大数据产业面临的问题 编辑:程序博客网 时间:2024/06/06 13:11
Magic boy Bi Luo with his excited string problem
题意:
给出<=15个字母串,每个串不超过10个字符,然后一个人开始写字母,每次随机写一个字母,直到出现给出的任意一个串,然后就停止,问写的长度的期望,答案mod 1e9+7。
思路:
总共150个字母比较少,用ac自动机建立转移矩阵,
每个状态可以写一个方程:
然后乘个26解决分数,移项过去就变成矩阵形式了。
//// main.cpp// 1025//// Created by 翅膀 on 16/9/16.// Copyright © 2016年 kg20006. All rights reserved.//#include <iostream>#include <queue>#include <stdio.h>#include <algorithm>#include <math.h>#include <string.h>using namespace std;typedef long long ll;const ll mod = 1e9+7;const int N = 155;ll qpow(ll a, ll k) { ll res = 1; a = (a%mod+mod)%mod; while(k) { if(k&1) res = (res*a)%mod; a = (a*a)%mod; k >>= 1; } return res;}ll a[N][N];ll x[N];void swapcol(int x, int y, int row){ for(int i = 0; i < row; ++i){ swap(a[i][x], a[i][y]); }}void getans(int row, int col){ for(int i = col-1; i >= 0; --i){ ll tmp = a[i][col]; for(int j = i+1; j < col; ++j){ tmp = ((tmp-a[i][j]*x[j]%mod)%mod+mod)%mod; } ll X = tmp*qpow(a[i][i], mod-2)%mod; x[i] = X; }}int Gauss(int row, int col){ int r = 0, c = 0; for(; r < row && c < col; ++r, ++c){ int mx = r; for(int i = r+1; i < row; ++i){ if(abs(a[i][c]) > abs(a[mx][c])) mx = i; } if(mx != r) swap(a[mx], a[r]); if(a[r][c] == 0){ r--; continue; } for(int i = r+1; i < row; ++i){ if(!a[i][c]) continue; ll tmp1 = a[r][c], tmp2 = a[i][c]; for(int j = c; j <= col; ++j){ a[i][j] = (a[i][j]*tmp1 - a[r][j]*tmp2)%mod; if(a[i][j] < 0) a[i][j] += mod; } } } for(int i = r; i < row; ++i){ if(a[i][col]) return -1; } int free_x = col-r; //自由元的个数 for(int i = 0, j; i < col && i < row; ++i){ if(!a[i][i]){ for(j = i+1; j < col; ++j) if(a[i][j]) break; if(j < col) swapcol(i, j, row); } } getans(row, col); return free_x;}struct Trie{ static const int MX = 155; int son[MX][26], fail[MX], end[MX]; int root, alloc; int newnode(){ memset(son[++alloc], 0, sizeof(son[alloc])); end[alloc] = 0, fail[alloc] = 0; return alloc; } void init(){ alloc = 0; root = newnode(); } void insert(char *s) { int p = root; for(int i = 0; s[i]; ++i) { if(son[p][s[i]-'a'] == 0) son[p][s[i]-'a'] = newnode(); p = son[p][s[i]-'a']; } end[p] = 1; } void build() { queue<int>q; for(int i = 0; i < 26; ++i) { if(son[root][i] == 0) son[root][i] = root; else fail[son[root][i]] = root, q.push(son[root][i]); } while(!q.empty()){ int u = q.front(); q.pop(); if(end[fail[u]]) end[u] = 1; for(int i = 0; i < 26; ++i) { if(son[u][i] == 0) son[u][i] = son[fail[u]][i]; else fail[son[u][i]] = son[fail[u]][i], q.push(son[u][i]); } } } ll DP(){ memset(a, 0, sizeof(a)); memset(x, 0, sizeof(x)); for(int i = 1; i <= alloc; ++i){ if(end[i]){ a[i-1][i-1] = 1; a[i-1][alloc] = 0; continue; } a[i-1][i-1] = 26; for(int j = 0; j < 26; ++j) { a[i-1][son[i][j]-1] -= 1; } a[i-1][alloc] = 26; } Gauss(alloc, alloc); return x[0]; }}ac;char s[25];int main(int argc, const char * argv[]) { int T, ca = 1; scanf("%d", &T); while(T--) { ac.init(); int n; scanf("%d", &n); for(int i = 0; i < n; ++i) { scanf("%s", s); ac.insert(s); } ac.build(); printf("Case #%d: %lld\n", ca++, ac.DP()); } return 0;}
0 0
- [AC自动机+期望DP] 玲珑ACM 1025 - Magic boy Bi Luo with his excited string problem
- 自动机+高斯消元 ifrog1025 Magic boy Bi Luo with his excited string problem
- HDU 5834 Magic boy Bi Luo with his excited tree
- hdu 5834 Magic boy Bi Luo with his excited tree
- HDU 5834 Magic boy Bi Luo with his excited tree
- hdu 5834 Magic boy Bi Luo with his excited tree
- hdu5834 Magic boy Bi Luo with his excited tree
- hdu5834 Magic boy Bi Luo with his excited tree
- Magic boy Bi Luo with his excited tree
- 树型dp hdu5834 Magic boy Bi Luo with his excited tree
- hdu 5834 Magic boy Bi Luo with his excited tree 树形dp
- HDU 5834 Magic boy Bi Luo with his excited tree 树形DP ★ ★
- hdu 5834 Magic boy Bi Luo with his excited tree (树形dp)
- hdu 5834 Magic boy Bi Luo with his excited tree (树形dp)
- 【HDOJ 5834】Magic boy Bi Luo with his excited tree(树型DP)
- Hdu-5834 Magic boy Bi Luo with his excited tree(树形DP)
- hdu5834 Magic boy Bi Luo with his excited tree(树形dp)
- HDU 5834 Magic boy Bi Luo with his excited tree(树形dp)
- 第三周项目四 顺序表应用
- 什么是重载,什么是重写?区别?
- 20160917iOS音频开发之资源(AVAsset)与元数据,解决获取资源属性问题(二)
- c++ destructor && lua garbage collection
- Hive知识点四(函数)
- [AC自动机+期望DP] 玲珑ACM 1025 - Magic boy Bi Luo with his excited string problem
- 详解大端模式和小端模式
- cygwin错误
- C语言解题报告模板
- eclipse 编程快捷键
- POJ1003
- BZOJ2081 [Poi2010]Beads
- 打印二叉树所有的路径
- illegal instruction非法指令Makefile设置CFLAGS = -march=armv6无效解决方法