HDU 2243 考研路茫茫——单词情结 ( Trie图 && DP && 矩阵构造幂和 )
题意 : 长度不超过L,只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个呢?这里就不考虑单词是否有实际意义。
比如一共有2个词根 aa 和 ab ,则可能存在104个长度不超过3的单词,分别为
(2个) aa,ab,
(26个)aaa,aab,aac...aaz,
(26个)aba,abb,abc...abz,
(25个)baa,caa,daa...zaa,
(25个)bab,cab,dab...zab。
分析 : 这题和 POJ 2778 非常相似,如果没有做过 POJ 2778 建议先去搞定那道题。此题难点就在于这个是要求不超过 L 长度包含词根的单词,根据解决 POJ 2778 的经验,我们可以得出 答案 = 总单词种类数 - 不包含词根的单词数。首先总单词数可以很容易想到为 261 + 262 + 263 + ..... + 26L ,而不包含词根的单词总数可以这样得到 ==> 假设原 Trie 图构建出来的状态矩阵为 A ,那么同样的我们需要构造一个幂和即 A1 + A2 + A3 + ..... + AL 然后最后的答案便是 ∑AL(0, i) ( i ∈ 1~矩阵长度 ) ,那怎么去构造这两个幂和呢?

只要利用这个公式即可,用原矩阵 + 单位矩阵 + 零矩阵构造出新矩阵,最后右上角的矩阵便是幂和的矩阵!
这里还有一点要注意,就是对于 2^64次方求模有一个很巧的方法,也就是直接定义为 unsigned long long (范围 : 0 ~ 2^64 -1),溢出就相当于求模了!
#include<string.h>
#include<stdio.h>
#include<iostream>
#include<queue>
#define ULL unsigned long long
using namespace std;
;
;
int maxn;///矩阵的大小
];
][]; }unit, M;
mat operator * (mat a, mat b){
mat ret;
; i<maxn; i++){
; j<maxn; j++){
ret.m[i][j] = (ULL);
; k<maxn; k++){
ret.m[i][j] += a.m[i][k]*b.m[k][j];
}
}
}
return ret;
}
inline void init_unit() {
; i<maxn; i++)
unit.m[i][i] = ;
}
mat pow_mat(mat a, long long n){
mat ret = unit;
while(n){
) ret = ret * a;
a = a*a;
n >>= ;
}
return ret;
}
struct Aho{
struct StateTable{
int Next[Letter];
int fail, flag;
}Node[Max_Tot];
int Size;
queue<int> que;
inline void init(){
while(!que.empty()) que.pop();
memset(Node[].Next, , ].Next));
Node[].fail = Node[].flag = ;
Size = ;
}
inline void insert(char *s){
;
; s[i]; i++){
int idx = s[i] - 'a';
if(!Node[now].Next[idx]){
memset(Node[Size].Next, , sizeof(Node[Size].Next));
Node[Size].fail = Node[Size].flag = ;
Node[now].Next[idx] = Size++;
}
now = Node[now].Next[idx];
}
Node[now].flag = ;
}
inline void BuildFail(){
Node[].fail = -;
; i<Letter; i++){
].Next[i]){
Node[Node[].Next[i]].fail = ;
que.push(Node[].Next[i]);
}].Next[i] = ;///必定指向根节点
}
while(!que.empty()){
int top = que.front(); que.pop();
;
; i<Letter; i++){
int &v = Node[top].Next[i];
if(v){
que.push(v);
Node[v].fail = Node[Node[top].fail].Next[i];
}else v = Node[Node[top].fail].Next[i];
}
}
}
inline void BuildMatrix(){
; i<Size; i++)
; j<Size; j++)
M.m[i][j] = ;
; i<Size; i++){
; j<Letter; j++){
if(!Node[i].flag && !Node[ Node[i].Next[j] ].flag)
M.m[i][Node[i].Next[j]]++;
}
}
maxn = Size;
}
}ac;
ULL GetSum(long long num){
mat ret;
ret.m[][] = ;
ret.m[][] = ;
ret.m[][] = ;
ret.m[][] = ;
int tmp = maxn;
maxn = ;
ret = pow_mat(ret, ++num);
maxn = tmp;
][]-;
}
ULL GetElimination(long long num){
mat tmp;
; i<maxn; i++)///左上角 为 原矩阵
; j<maxn; j++)
tmp.m[i][j] = M.m[i][j];
; i<maxn; i++)///右上角 为 单位矩阵
); j++)
tmp.m[i][j] = (i+maxn == j);
); i++)///左下角 为 零矩阵
; j<maxn; j++)
tmp.m[i][j] = ;
); i++)///右下角 为 单位矩阵
); j++)
tmp.m[i][j] = (i==j);
int Temp = maxn;
maxn <<= ;///先将原本矩阵的大小放大一倍进行快速幂运算,这个和我快速幂的写法有关
tmp = pow_mat(tmp, ++num);
ULL ret = (ULL);
maxn = Temp;///再回复成原来大小
); i++)///右上角的矩阵就是幂和了
ret += tmp.m[][i];
return (--ret);///需要 -1
}
int main(void)
{
int n, m;
while(~scanf("%d %d", &m, &n)){
ac.init();
; i<m; i++){
scanf("%s", S);
ac.insert(S);
}
ac.BuildFail();
ac.BuildMatrix();
init_unit();
ULL Tot = GetSum((long long)n);///注意是传long long不然会爆int
ULL Elimination = GetElimination((long long)n);
cout<<Tot-Elimination<<endl;
}
;
}
HDU 2243 考研路茫茫——单词情结 ( Trie图 && DP && 矩阵构造幂和 )的更多相关文章
- HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- HDU 2243 考研路茫茫――单词情结 ——(AC自动机+矩阵快速幂)
和前几天做的AC自动机类似. 思路简单但是代码200余行.. 假设solve_sub(i)表示长度为i的不含危险单词的总数. 最终答案为用总数(26^1+26^2+...+26^n)减去(solve_ ...
- HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
http://acm.hdu.edu.cn/showproblem.php?pid=2243 题意: 给出m个模式串,求长度不超过n的且至少包含一个模式串的字符串个数. 思路: 如果做过poj2778 ...
- HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵)
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 2243 考研路茫茫——单词情结(AC自动机+DP+快速幂)
题目链接 错的上头了... 这题是DNA的加强版,26^1 +26^2... - A^1-A^2... 先去学了矩阵的等比数列求和,学的是第二种方法,扩大矩阵的方法.剩下就是各种模板,各种套. #in ...
- hdu 2243 考研路茫茫——单词情结(AC自动+矩阵)
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 2243 考研路茫茫——单词情结
考研路茫茫——单词情结 Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID ...
- hdu 2243 考研路茫茫——单词情结 ac自动机+矩阵快速幂
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2243 题意:给定N(1<= N < 6)个长度不超过5的词根,问长度不超过L(L <23 ...
- HDU 2243 考研路茫茫——单词情结 求长度小于等于L的通路总数的方法
http://acm.hdu.edu.cn/showproblem.php?pid=2243 这是一题AC自动机 + 矩阵快速幂的题目, 首先知道总答案应该是26^1 + 26^2 + 26^3 .. ...
随机推荐
- 【MM系列】SAP 各种冲销凭证
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP 各种冲销凭证 前言部分 ...
- windows下重启nginx
参考:从零学nginx-windows下reload配置无效及如何重启 因为Nginx是多进程模型,有一个主进程和多个子进程,主进程只负责管理子进程,基本的网络事件由各个子进程处理. 所以有时候当我们 ...
- [多校联考2019(Round 4 T1)][51nod 1295]Xor key(可持久化trie)
[51nod 1295]Xor key(可持久化trie) 题面 给出一个长度为n的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求A[L] 至 A[R] ...
- Rest_Framework常用插件
1. 认证Authentication 可以在配置文件中配置全局默认的认证方案 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest ...
- Scala学习笔记(6)对象
1.单例对象.Scala没有静态方法或字段,可以使用object这个语法结构来达到同样的目的.对象定义了单个实例,包含了你想要的特性. object Accounts{ def newUniqueNu ...
- 什么是CPC,CPA,CVR,CTR,ROI
合格的网络营销人员都应该熟悉下面的常见英文缩写,这些都是我们必须知道的名词解释:CVR (Click Value Rate): 转化率,衡量CPA广告效果的指标CTR (Click Through R ...
- 流畅的Python (Fluent Python) —— 第一部分
Python 最好的品质之一是一致性. 魔术方法(magic method)是特殊方法的昵称.特殊方法也叫双下方法. 1.1 一摞Python风格的纸牌 import collections Card ...
- 02MySQL数据库
1.MySQL启动和关闭 2.登录MySQL数据库 MySQL是一个需要账户名密码登录的数据库,登陆后使用,它提供了一个默认的root账号,使用安装时设置的密码即可登录. 格式1:cmd> m ...
- 洛谷 P2622 关灯问题II (状态压缩+BFS)
题目描述 现有n盏灯,以及m个按钮.每个按钮可以同时控制这n盏灯--按下了第i个按钮,对于所有的灯都有一个效果.按下i按钮对于第j盏灯,是下面3中效果之一:如果a[i][j]为1,那么当这盏灯开了的时 ...
- hdu2955_Robberies 01背包
有一个强盗要去几个银行偷盗,他既想多投点钱,又想尽量不被抓到.已知各个银行 的金钱数和被抓的概率,以及强盗能容忍的最大被抓概率.求他最多能偷到多少钱? 解:以概率为价值 问价值在合理范围背包的最大容量 ...