题目

为什么没人用\(SAM\)啊

我们先把原来的模式串建一遍\(SAM\),之后我们就可以求出\(SAM\)上每一个节点的\(|endpos|\)就可以知道每一个子串出现的次数了,也就是在模式串上的匹配数了

之后我们设\(dp[i][j]\)表示前\(i\)个里组合出的子串在\(SAM\)上匹配到了\(j\)位置的方案数是多少,转移的时候就枚举每一个子串以及\(SAM\)上的每一个节点之后跑匹配就好了

最后的答案就是

\[\sum_{i=1}^{cnt}dp[m][i]\times sz[i]
\]

之后第一维甚至可以直接滚动掉

代码

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstring>
  4. #include<cstdio>
  5. #define maxn 100005
  6. #define re register
  7. #define LL long long
  8. #define max(a,b) ((a)>(b)?(a):(b))
  9. #define min(a,b) ((a)<(b)?(a):(b))
  10. const int mod=1e9+7;
  11. struct E{int v,nxt;}e[maxn<<1];
  12. int fa[maxn<<1],son[maxn<<1][26],len[maxn<<1],head[maxn<<1],sz[maxn<<1];
  13. char S[maxn];
  14. int dp[2][maxn<<1];
  15. int n,m,num,cnt=1,lst=1,ans,o;
  16. inline void add(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
  17. void dfs(int x) {for(re int i=head[x];i;i=e[i].nxt) dfs(e[i].v),sz[x]+=sz[e[i].v];}
  18. inline void ins(int c)
  19. {
  20. int f=lst,p=++cnt; lst=p;
  21. len[p]=len[f]+1,sz[p]=1;
  22. while(f&&!son[f][c]) son[f][c]=p,f=fa[f];
  23. if(!f) {fa[p]=1;return;}
  24. int x=son[f][c];
  25. if(len[f]+1==len[x]) {fa[p]=x;return;}
  26. int y=++cnt; len[y]=len[f]+1,fa[y]=fa[x],fa[x]=fa[p]=y;
  27. for(re int i=0;i<26;i++) son[y][i]=son[x][i];
  28. while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];
  29. }
  30. inline int find(int now) {for(re int i=1;i<=n;i++) {now=son[now][S[i]-'A'];if(!now) break;}return now;}
  31. int main()
  32. {
  33. scanf("%d",&m);scanf("%s",S+1);n=strlen(S+1);
  34. for(re int i=1;i<=n;i++) ins(S[i]-'A');
  35. for(re int i=2;i<=cnt;i++) add(fa[i],i);dfs(1);
  36. dp[0][1]=1; o=0;
  37. for(re int i=1;i<=m;i++)
  38. {
  39. int T; o^=1; scanf("%d",&T);
  40. for(re int j=1;j<=cnt;j++) dp[o][j]=0;
  41. for(re int j=1;j<=T;j++)
  42. {
  43. scanf("%s",S+1);n=strlen(S+1);
  44. for(re int k=1;k<=cnt;k++)
  45. if(dp[o^1][k]) {int v=find(k);if(v) dp[o][v]=(dp[o][v]+dp[o^1][k])%mod;}
  46. }
  47. }
  48. for(re int i=2;i<=cnt;i++) ans=(ans+(LL)dp[o][i]*(LL)sz[i]%mod)%mod;
  49. printf("%d\n",ans);
  50. return 0;
  51. }

【[TJOI2018]碱基序列】的更多相关文章

  1. 洛谷P4591 [TJOI2018]碱基序列(hash dp)

    题意 题目链接 Sol \(f[i][j]\)表示匹配到第\(i\)个串,当前在主串的第\(j\)个位置 转移的时候判断一下是否可行就行了.随便一个能搞字符串匹配的算法都能过 复杂度\(O(|S| K ...

  2. [TJOI2018]碱基序列

    嘟嘟嘟 现在看到字符串就想到SAM,所以很担心kmp啥的会不会忘了-- 这题感觉挺暴力的:首先当然要把\(s\)建成SAM,然后令\(dp[i][j]\)表示到第\(i\)组时,SAM上节点\(j\) ...

  3. BZOJ5337 [TJOI2018] 碱基序列 【哈希】【动态规划】

    题目分析: 这道题的难点在于要取模,而题面没有写. 容易想到一个O(1E7)的dp.KMP或者哈希得到相关位置然后对于相关位置判断上一个位置有多少种情况. 代码: #include<bits/s ...

  4. 洛谷P4591 [TJOI2018]碱基序列 【KMP + dp】

    题目链接 洛谷P4591 题解 设\(f[i][j]\)表示前\(i\)个串匹配到位置\(j\)的方案数,匹配一下第\(i\)个串进行转移即可 本来写了\(hash\),发现没过,又写了一个\(KMP ...

  5. 「学习笔记」字符串基础:Hash,KMP与Trie

    「学习笔记」字符串基础:Hash,KMP与Trie 点击查看目录 目录 「学习笔记」字符串基础:Hash,KMP与Trie Hash 算法 代码 KMP 算法 前置知识:\(\text{Border} ...

  6. bzoj 5338: [TJOI2018]xor (树链剖分+可持久化01Trie)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=5338 题面: 5338: [TJOI2018]xor Time Limit: 30 Sec  ...

  7. [模板] dp套dp && bzoj5336: [TJOI2018]party

    Description Problem 5336. -- [TJOI2018]party Solution 神奇的dp套dp... 考虑lcs的转移方程: \[ lcs[i][j]=\begin{ca ...

  8. 洛谷P4590 [TJOI2018]游园会(状压dp LCS)

    题意 题目链接 Sol 这个题可能是TJOI2018唯一的非模板题了吧.. 考虑LCS的转移方程, \[f[i][j] = max(f[i - 1][j], f[i][j - 1], f[i - 1] ...

  9. 【BZOJ5339】[TJOI2018]教科书般的亵渎(斯特林数)

    [BZOJ5339][TJOI2018]教科书般的亵渎(斯特林数) 题面 BZOJ 洛谷 题解 显然交亵渎的次数是\(m+1\). 那么这题的本质就是让你求\(\sum_{i=1}^n i^{m+1} ...

随机推荐

  1. hive 全表全字段对比

    select * from ( select max(t1.source) as source ,t1.c1 ,t1.c2 ,t1.c3 ,count(*) as cnt from ( as sour ...

  2. 技巧:Ubuntu踩坑记之网络配置哪里找

    今天在虚拟机中遇到一个关于网络配置的坑,在此记录下来. 我们都知道虚拟机系统(此处指的是vmware)中,虚拟网络主要由三个方式实现: 桥接网络 NAT转换 主机共享网络 在这三种方式下,一般我们使用 ...

  3. sf01_什么是数据结构

    数据结构解决什么问题 如何在计算机中存储数据和信息,采用什么样的方法和技巧加工处理这些数据,都是数据结构需要努力解决的问题. 解决问题的步骤 使用计算机解决问题的步骤:分析具体问题得到数学模型,设计解 ...

  4. TCP/IP协议中几个缩写词的含义 MSL、TTL和RTT 报文最大生存时间 跳数(即生存时间) cs往返时间 MSL要大于TTL知道为什么吗?

    MSL.TTL和RTT简介 1.MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃.因为 ...

  5. SQL---MySQL数据库---聚合函数

    1.数值 format(x,n) 将x格式化为  由逗号分隔,小数点后n 位的数:

  6. RTT之内核服务函数

    一 延时函数: rt_thread_delay(t) //调用时进入系统调度. rt_kprintf()函数在kservice.c中实现,如果不使用设备驱动,则由自定义函数void rt_hw_con ...

  7. 电感的Q值

    电感的Q值又称为品质因数,即在通过一定频率信号时,感抗与等效损耗之比.品质因数越高即系统损耗越小效率越高,一般为50`100,最高500左右,再大就会烧毁.一般Q值与很多因素有关:绕线粗细,长度与直径 ...

  8. eleme 项目使用到的库

    探索eleme用到的库 xml re库 通过regex = re.compile(pattern)返回一个pattern对象, 通过该对象匹配正则表达式的字符串, 最好在模式中使用r'some'原始字 ...

  9. HDU——Cover——————【技巧】

    Cover Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  10. java的wait/notify小结

    wait()是使线程停止运行,而notify使停止的线程继续运行 wait()锁释放与notify()锁不释放 当线程呈wait状态时,调用线程对象的interrupt()方法会出现异常 带一个参数的 ...