问你长度为1~N的串中包含了模式串的串总共有几个(先求出总共小于L的单词数(26^1+26^2+26^3+...26^L)..然后再减去不包括所给字符串的单词)

答案要模2^64,直接用unsinged __int64!!!!

算法:AC自动机+二分求等比矩阵和+二分求等比数列和

(ps:

等比矩阵求和(或等比数列),有经典算法,假定原矩阵为A,阶数为n,那么构造一个阶数为2n的矩阵,如下
      | A   E |         其中O代表O矩阵,E代表单位矩阵,这样,求出的K次矩阵的右上n子矩阵正好是
      | O   E |         等比矩阵的K项和,这种构造法比我实现的两次二分快了4倍左右。

这里有个错误要注意...求出K次矩阵的右上子矩阵应该是K-1项的和...

//#pragma comment(linker, "/STACK:102400000")
#include<cstdlib>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<vector>
#define tree int o,int l,int r
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
#define lo o<<1
#define ro o<<1|1
#define pb push_back
#define mp make_pair
#define ULL unsigned long long
#define inf 0x7fffffff
#define eps 1e-7
#define N 35
#define M 26
using namespace std;
//void print2(ULL ma[][N],int n,int m)
//{
//    cout<<"=============="<<endl;
//    for (int i=0; i<n ; i++ )
//    {
//        printf("%d",ma[i][0]);
//        for (int j=1; j<m ; j++)
//            printf(" %d",ma[i][j]);
//        cout<<endl;
//    }
//    cout<<"-----------"<<endl;
//}int m,n,T,t,x,y,u;
int ch[N][M];
int v[N];
int f[N],last[N],num;
ULL ma[N][N],temp[N][N],sum[N][N],sum2[N][N],ans;
ULL he,maxv;
void clear()//Trie树初始化
{num=1;memset(ma,0,sizeof(ma));memset(sum,0,sizeof(sum));memset(ch[0],0,sizeof(ch[0]));memset(v,0,sizeof(v));memset(last,0,sizeof(last));
}
int idx(char c)
{return c-'a';
}
void insert(char str[],int value)//建Trie树
{int len=strlen(str);int u=0;for (int i=0; i<len; ++i ){int c=idx(str[i]);if(!ch[u][c])//保存的是结点坐标
        {memset(ch[num],0,sizeof(ch[num]));ch[u][c]=num++;//
        }u=ch[u][c];}v[u]=value;
}
void getac()
{queue<int> q;//保存的节点下标f[0]=0;for (int c=0; c<M; ++c ){int u=ch[0][c];if(u)//不需要优化的else
        {q.push(u);f[u]=0;last[u]=v[u];//WA
        }}while(!q.empty()){int r=q.front();q.pop();for (int c=0; c<M; ++c )//注意:c表示节点值,不是结点位置
        {int u=ch[r][c];if(u){q.push(u);int s=f[r];
//                while(s&&ch[s][c]==0)s=f[s];//可以简化f[u]=ch[s][c];last[u]=(v[u]||last[f[u]]);////
//                last[u]=v[f[u]]?f[u]:last[f[u]];
            }else //重要优化ch[r][c]=ch[f[r]][c];}}
}
char str[20];
void build()
{for(int i=0; i<num; i++){for(int j=0; j<M; j++){int u=ch[i][j];if(last[u]==0)ma[i][u]++;}}
}
void multi(ULL a[][N],ULL b[][N],int n)
{ULL c[N][N]= {0};for(int i=0; i<n; i++)for(int j=0; j<n; j++)for(int k=0; k<n; k++){c[i][j]+=a[i][k]*b[k][j];}memcpy(a,c,sizeof(c));
}
void mat(int n,int num)
{if(n==1){for(int i=0; i<num; i++)for(int j=0; j<num; j++)sum[i][j]=temp[i][j]=ma[i][j];he=maxv=26;}else{mat(n/2,num);memcpy(sum2,sum,sizeof(sum));multi(sum,temp,num);for(int i=0; i<num; i++)for(int j=0; j<num; j++)sum[i][j]+=sum2[i][j];multi(temp,temp,num);ULL hhh=he;he*=maxv;he+=hhh;maxv*=maxv;if(n&1){maxv*=26;he+=maxv;multi(temp,ma,num);for(int i=0; i<num; i++)for(int j=0; j<num; j++)sum[i][j]+=temp[i][j];}}
}
int main()
{
#ifndef ONLINE_JUDGEfreopen("ex.in","r",stdin);
#endifint ncase=0;while(scanf("%d%d%*c",&m,&n)==2){clear();while(m--){scanf("%s",str);insert(str,1);}getac();build();ans=0;mat(n,num);for(int i=0; i<num; i++){ans+=sum[0][i];}printf("%I64u\n",he-ans);//%I64u
    }return 0;
}

View Code

转载于:https://www.cnblogs.com/sbaof/p/3374592.html

hdu 2243(poj2778的加强版!(AC自动机+矩阵))相关推荐

  1. L. Poor God Water(ACM-ICPC 2018 焦作赛区网络预赛,ac自动机+矩阵快速幂 或 BM线性递推)

    描述 God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells hi ...

  2. HDU - 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)

    题目链接:点击查看 题目大意:给出 n 个词根,现在要求出长度不大于 len 的单词中,有多少单词包含至少一个词根 题目分析:如果我们反过来想,也就是求出来总的单词数,然后减去不包含词根的单词数,剩下 ...

  3. hdu 3962(AC自动机+矩阵优化dp)

    转载标记处:http://blog.csdn.net/woshi250hua/article/details/7599472 题目大意:给定m个DNA病毒序列,求碱基构成的长度为n且含有两个以上DNA ...

  4. 【bzoj1444】[Jsoi2009]有趣的游戏 AC自动机+矩阵乘法

    题目描述 输入 注意 是0<=P 输出 样例输入 样例输出 题解 AC自动机+矩阵乘法 先将所有字符串放到AC自动机中,求出Trie图. 然后构建邻接矩阵:如果x不是某个字符串的末位置,则x连向 ...

  5. HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)

    背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...

  6. 【距离GDOI:128天】【POJ2778】DNA Sequence(AC自动机+矩阵加速)

    已经128天了?怎么觉得上次倒计时150天的日子还很近啊 ....好吧为了把AC自动机搞透我也是蛮拼的..把1030和这道题对比了无数遍...最终结论是...无视时间复杂度,1030可以用这种写法解. ...

  7. hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)

    题目链接:hdu_2243_考研路茫茫--单词情结 题意: 让你求包含这些模式串并且长度不小于L的单词种类 题解: 这题是poj2788的升级版,没做过的强烈建议先做那题. 我们用poj2778的方法 ...

  8. POJ 2778 DNA Sequence —— (AC自动机+矩阵快速幂)

    距离上次做AC自动机有很久了=.=,以前这题的思路死活看不懂,现在还是觉得很好理解的. 思路参见:http://blog.csdn.net/morgan_xww/article/details/783 ...

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

    题目链接:点击查看 题目大意:给出 n 个长度不大于 10 的字符串表示病毒串,再给出一个长度 len ,问长度为 len 的字符串中,有多少个字符串不含有病毒串作为子串 题目分析:因为病毒串的长度和 ...

最新文章

  1. 打开脑科学研究的另一扇窗:脑神经化学活体原位电化学分析新技术
  2. java http客户端_java 11 标准Java异步HTTP客户端
  3. vim补全html标签,vim括号引号html标签自动补全
  4. cad2010背景怎么调成黑色_买皮蛋时,黄色和黑色的有什么区别?哪种更好?看完涨知识了...
  5. 【11GR2 RAC】如何开启归档和FLASHBACK
  6. Hadoop 集群搭建
  7. mysql内部参数是什么意思_mysql参数及解释
  8. vertica 数据库 linux,配置访问列式数据库vertica的php环境
  9. mysql大数据高并发处理
  10. 手动配置 hibernate 项目
  11. 关于如何用python下载文件
  12. 以下mysql说法正确的是_下面关于 MySQL 的说法中,正确的是_商务统计学答案_学小易找答案...
  13. 一文看懂中国的金融体系
  14. 中石油邮箱pop3服务器,手机客户端访问中油邮箱设置
  15. 机器学习中的数学——距离定义(一):欧几里得距离(Euclidean Distance)
  16. ffmpeg水平翻转视频,附批量处理脚本
  17. Android Studio如何更改app名称
  18. 钓鱼邮件从入门到放弃
  19. 京东超级秒杀时间html,京东418超级秒杀节LOGO及使用规范
  20. Interviewing at Amazon — Leadership Principles Reading Notes

热门文章

  1. 192.168.8.1手机登陆_192.168.8.1登录入口
  2. $_server[#039;php_auth_user#039;],ecshop中$user ($GLOBALS[#039;user#039;])对象在哪里定义的...
  3. 一则故事表达:并发,并行,同步,异步,线程,多线程
  4. ios 图片裁剪框架_iOS 图片裁剪与修改
  5. iphone怎么查看wifi密码_WiFi密码忘了怎么办?一秒找回密码
  6. vs 堆栈保留大小_新娘妆前vs妆后!看过就知道化妆师的重要性了!
  7. Matplotlib库入门
  8. 深度学习入门笔记(四):神经网络
  9. 2018蓝桥模拟赛(一) 数独(dfs)
  10. 如何在终端编辑文件并保存