hdu 2243(poj2778的加强版!(AC自动机+矩阵))
问你长度为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自动机+矩阵))相关推荐
- 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 ...
- HDU - 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
题目链接:点击查看 题目大意:给出 n 个词根,现在要求出长度不大于 len 的单词中,有多少单词包含至少一个词根 题目分析:如果我们反过来想,也就是求出来总的单词数,然后减去不包含词根的单词数,剩下 ...
- hdu 3962(AC自动机+矩阵优化dp)
转载标记处:http://blog.csdn.net/woshi250hua/article/details/7599472 题目大意:给定m个DNA病毒序列,求碱基构成的长度为n且含有两个以上DNA ...
- 【bzoj1444】[Jsoi2009]有趣的游戏 AC自动机+矩阵乘法
题目描述 输入 注意 是0<=P 输出 样例输入 样例输出 题解 AC自动机+矩阵乘法 先将所有字符串放到AC自动机中,求出Trie图. 然后构建邻接矩阵:如果x不是某个字符串的末位置,则x连向 ...
- HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)
背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...
- 【距离GDOI:128天】【POJ2778】DNA Sequence(AC自动机+矩阵加速)
已经128天了?怎么觉得上次倒计时150天的日子还很近啊 ....好吧为了把AC自动机搞透我也是蛮拼的..把1030和这道题对比了无数遍...最终结论是...无视时间复杂度,1030可以用这种写法解. ...
- hdu_2243_考研路茫茫——单词情结(AC自动机+矩阵)
题目链接:hdu_2243_考研路茫茫--单词情结 题意: 让你求包含这些模式串并且长度不小于L的单词种类 题解: 这题是poj2788的升级版,没做过的强烈建议先做那题. 我们用poj2778的方法 ...
- POJ 2778 DNA Sequence —— (AC自动机+矩阵快速幂)
距离上次做AC自动机有很久了=.=,以前这题的思路死活看不懂,现在还是觉得很好理解的. 思路参见:http://blog.csdn.net/morgan_xww/article/details/783 ...
- POJ - 2778 DNA Sequence(AC自动机+矩阵快速幂)
题目链接:点击查看 题目大意:给出 n 个长度不大于 10 的字符串表示病毒串,再给出一个长度 len ,问长度为 len 的字符串中,有多少个字符串不含有病毒串作为子串 题目分析:因为病毒串的长度和 ...
最新文章
- 打开脑科学研究的另一扇窗:脑神经化学活体原位电化学分析新技术
- java http客户端_java 11 标准Java异步HTTP客户端
- vim补全html标签,vim括号引号html标签自动补全
- cad2010背景怎么调成黑色_买皮蛋时,黄色和黑色的有什么区别?哪种更好?看完涨知识了...
- 【11GR2 RAC】如何开启归档和FLASHBACK
- Hadoop 集群搭建
- mysql内部参数是什么意思_mysql参数及解释
- vertica 数据库 linux,配置访问列式数据库vertica的php环境
- mysql大数据高并发处理
- 手动配置 hibernate 项目
- 关于如何用python下载文件
- 以下mysql说法正确的是_下面关于 MySQL 的说法中,正确的是_商务统计学答案_学小易找答案...
- 一文看懂中国的金融体系
- 中石油邮箱pop3服务器,手机客户端访问中油邮箱设置
- 机器学习中的数学——距离定义(一):欧几里得距离(Euclidean Distance)
- ffmpeg水平翻转视频,附批量处理脚本
- Android Studio如何更改app名称
- 钓鱼邮件从入门到放弃
- 京东超级秒杀时间html,京东418超级秒杀节LOGO及使用规范
- Interviewing at Amazon — Leadership Principles Reading Notes
热门文章
- 192.168.8.1手机登陆_192.168.8.1登录入口
- $_server[#039;php_auth_user#039;],ecshop中$user ($GLOBALS[#039;user#039;])对象在哪里定义的...
- 一则故事表达:并发,并行,同步,异步,线程,多线程
- ios 图片裁剪框架_iOS 图片裁剪与修改
- iphone怎么查看wifi密码_WiFi密码忘了怎么办?一秒找回密码
- vs 堆栈保留大小_新娘妆前vs妆后!看过就知道化妆师的重要性了!
- Matplotlib库入门
- 深度学习入门笔记(四):神经网络
- 2018蓝桥模拟赛(一) 数独(dfs)
- 如何在终端编辑文件并保存