HDU2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
与POJ2778一样。这题是求长度不超过n且包含至少一个词根的单词总数。
长度不超过n的单词总数记为Sn,长度不超过n不包含词根的单词总数记为Tn。
答案就是,Sn-Tn。
Sn=26+262+263+...+26n
Tn=A+A2+A3+...+An (A为AC自动机构造出来的矩阵)
可以构造矩阵用快速幂求出Sn和Tn:
$$ \begin{bmatrix} 26 & 1 \\ 0 & 1 \end{bmatrix} \times \begin{bmatrix} S_n \\ 26 \end{bmatrix} = \begin{bmatrix} S_{n+1} \\ 26 \end{bmatrix}$$
$$ \begin{bmatrix} A & E \\ 0 & E \end{bmatrix} \times \begin{bmatrix} T_n \\ A \end{bmatrix} = \begin{bmatrix} T_{n+1} \\ A \end{bmatrix}$$
通过 $ \begin{bmatrix} 26 & 1 \\ 0 & 1 \end{bmatrix} ^n \times \begin{bmatrix} S_0 \\ 26 \end{bmatrix} = \begin{bmatrix} S_n \\ 26 \end{bmatrix}$ 即可得到Sn,其中S0=0,Tn同理。
另外题目结果mod 264这个直接把变量定义为unsigned __int64即可,溢出位数自动舍去。
- #include<cstdio>
- #include<cstring>
- #include<queue>
- using namespace std;
- int tn,ch[][],fail[];
- bool flag[];
- void insert(char *s){
- int x=;
- for(int i=; s[i]; ++i){
- int y=s[i]-'a';
- if(ch[x][y]==) ch[x][y]=++tn;
- x=ch[x][y];
- }
- flag[x]=;
- }
- void init(int x){
- memset(fail,,sizeof(fail));
- queue<int> que;
- for(int i=; i<; ++i){
- if(ch[][i]) que.push(ch[][i]);
- }
- while(!que.empty()){
- int x=que.front(); que.pop();
- for(int i=; i<; ++i){
- if(ch[x][i]) que.push(ch[x][i]),fail[ch[x][i]]=ch[fail[x]][i];
- else ch[x][i]=ch[fail[x]][i];
- flag[ch[x][i]]|=flag[ch[fail[x]][i]];
- }
- }
- }
- void init(){
- memset(fail,,sizeof(fail));
- queue<int> que;
- for(int i=; i<; ++i){
- if(ch[][i]) que.push(ch[][i]);
- }
- while(!que.empty()){
- int now=que.front(); que.pop();
- for(int i=; i<; ++i){
- if(ch[now][i]) que.push(ch[now][i]),fail[ch[now][i]]=ch[fail[now]][i];
- else ch[now][i]=ch[fail[now]][i];
- flag[ch[now][i]]|=flag[ch[fail[now]][i]];
- }
- }
- }
- struct Mat{
- unsigned long long m[][];
- int n;
- };
- Mat operator*(const Mat &m1,const Mat &m2){
- Mat m={};
- m.n=m1.n;
- for(int i=; i<m.n; ++i){
- for(int j=; j<m.n; ++j){
- for(int k=; k<m.n; ++k) m.m[i][j]+=m1.m[i][k]*m2.m[k][j];
- }
- }
- return m;
- }
- int main(){
- int n,l;
- char str[];
- while(~scanf("%d%d",&n,&l)){
- tn=;
- memset(ch,,sizeof(ch));
- memset(flag,,sizeof(flag));
- while(n--){
- scanf("%s",str);
- insert(str);
- }
- init();
- Mat se={},sm={};
- se.n=sm.n=;
- for(int i=; i<; ++i) se.m[i][i]=;
- sm.m[][]=; sm.m[][]=; sm.m[][]=;
- n=l;
- while(n){
- if(n&) se=se*sm;
- sm=sm*sm;
- n>>=;
- }
- unsigned long long tot=se.m[][]*;
- Mat te={},tm={};
- te.n=tm.n=tn+<<;
- for(int i=; i<te.n; ++i) te.m[i][i]=;
- for(int i=; i<=tn; ++i){
- tm.m[i+tn+][i+tn+]=tm.m[i][i+tn+]=;
- }
- for(int i=; i<=tn; ++i){
- if(flag[i]) continue;
- for(int j=; j<; ++j){
- if(flag[ch[i][j]]) continue;
- ++tm.m[i][ch[i][j]];
- }
- }
- Mat tmp=tm; tmp.n=tn+;
- n=l;
- while(n){
- if(n&) te=te*tm;
- tm=tm*tm;
- n>>=;
- }
- Mat tmp2; tmp2.n=tn+;
- for(int i=; i<=tn; ++i){
- for(int j=tn+; j<te.n; ++j) tmp2.m[i][j-tn-]=te.m[i][j];
- }
- tmp=tmp*tmp2;
- unsigned long long res=;
- for(int i=; i<=tn; ++i){
- res+=tmp.m[][i];
- }
- printf("%llu\n",tot-res);
- }
- return ;
- }
HDU2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)的更多相关文章
- [hdu2243]考研路茫茫——单词情结(AC自动机+矩阵快速幂)
题意:长度不超过L,只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个. 解题关键:利用补集转化的思想,先求一个词根也不包含的单词个数,然后用总的减去即可.长度不超过L需要用矩阵维数增加一倍 ...
- hdu 2243 考研路茫茫——单词情结 ac自动机+矩阵快速幂
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2243 题意:给定N(1<= N < 6)个长度不超过5的词根,问长度不超过L(L <23 ...
- HDU 2243 考研路茫茫——单词情结(AC自动机+DP+快速幂)
题目链接 错的上头了... 这题是DNA的加强版,26^1 +26^2... - A^1-A^2... 先去学了矩阵的等比数列求和,学的是第二种方法,扩大矩阵的方法.剩下就是各种模板,各种套. #in ...
- HDU2243 考研路茫茫——单词情结 ——AC自动机、矩阵优化
题目链接:https://vjudge.net/problem/HDU-2243 考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memor ...
- hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)
题目链接:hdu_2243_考研路茫茫——单词情结 题意: 让你求包含这些模式串并且长度不小于L的单词种类 题解: 这题是poj2788的升级版,没做过的强烈建议先做那题. 我们用poj2778的方法 ...
- hdu 2243 考研路茫茫——单词情结 AC自动机 矩阵幂次求和
题目链接 题意 给定\(N\)个词根,每个长度不超过\(5\). 问长度不超过\(L(L\lt 2^{31})\),只由小写字母组成的,至少包含一个词根的单词,一共可能有多少个? 思路 状态(AC自动 ...
- HDU-2243 考研路茫茫——单词情结(AC自动机)
题目大意:给n个单词,长度不超过L的单词有多少个包含n个单词中的至少一个单词. 题目分析:用长度不超过L的单词书目减去长度在L之内所有不包含任何一个单词的书目. 代码如下: # include< ...
- hdu 2243 考研路茫茫——单词情结(AC自动+矩阵)
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu2243 考研路茫茫——单词情结【AC自动机】【矩阵快速幂】
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
随机推荐
- java笔记--异常详解与处理
一.异常概念 Throwable类是Java中所有错误或异常的超类. 1.只有当对象是此类(或其子类)的实例时,才能通过Java虚拟机或着Java throw语句抛出. 2.只有此类或其子类才 ...
- NGUI的部分控件无法更改layer?
http://momowing.diandian.com/post/2012-09-17/40038835795 今天狗日的遇到这样的问题,这是一个imagebutton:,它的层定义为:,NGUI里 ...
- NSDictionary转化为实体类对象
方法一: 使用objective-c NSObject自带的方法 setValuesForKeysWithDictionary:dict 作用是: 如果NSDictionary中的key和实体类对象的 ...
- Access数据库之偏移注入
/*转载请注明出处:珍惜少年时*/ 偏移注入主要是针对知道表,但是不知道字段的. 这里我已经知道了表明是:sys_admin 可以使用: select exists(selct * from sys_ ...
- 使用Cydia Substrate 从Native Hook Android Java世界
这里介绍了如何使用Cydia Substrate Hook安卓Java世界.这篇文章介绍如何从Native中Hook 安卓Java世界. 手机端配置见之前文章. 一.建立工程 建立一个Android工 ...
- CC MayClg 15 T3
www.codechef.com/MAY15/problems/CHAPD 一道比较神奇的题目... 看到题目后自己yy出了个傻逼算法...然后对拍都是对的...提交都是错的...然后一看" ...
- macosx zsh下安装rvm和ruby
1)curl -L get.rvm.io | bash -s stable 2)把下面一行加到~/.zshrc中: [[ -s "$HOME/.rvm/scripts/rvm" ] ...
- JQgrid for asp.net
转载自http://blog.csdn.net/shiworkyue/article/details/8283716 JQgrid for asp.net 网上资料较少,自己总结了些不全,能用到的可 ...
- mysql varchar
2013年9月13日 14:58:43 MYSQL的varchar数据类型 先说结论: 如果设置字段长度为30,字符编码为utf8,那么一个汉字算一个字符,一个数字算一个字符,一个字母也算一个字符 版 ...
- BestCoder10 1002 Revenge of GCD(hdu 5019) 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5019 题目意思:给出 X 和 Y,求出 第 K 个 X 和 Y 的最大公约数. 例如8 16,它们的公 ...