#179. 「2019冬令营提高组」原样输出

暴力对每个串建后缀自动机,然后暴力枚举每个自动机的子串。可以拿到部分分。

然鹅我们可以把每个后缀自动机连起来。

我们知道,后缀自动机是用最少的点(空间)表示出一个串的所有子串。

那么我们为啥不在后缀自动机上直接跑dp呢?于是我们把它们连起来。

复制一段ppt:

可以怎么拼呢?

我们考虑如何判断一个字符串是否是可能的输出文件

显然我们可以贪心地匹配,每次拿起一个输入串,一直匹配到不能再加字符了才放下,这样一定是正确的

于是我们可以告诉自动机如果失配了要往哪走

比如有一个节点没有C的转移边,那么就要向之后第一个包含字符C的字符串的后缀自动机接受字符串C的节点连一条C的转移边

当然如果这样的字符串不存在就不需要连边

把自动机建起来后

对于$k=1$的情况,直接dfs搞定

但是面对大数据,dfs显然是会TLE的鸭

但是仔细一看

对于 100% 的数据,保证输入文件大小不超过 1MB ,保证输出文件大小不超过 200MB 。

显然大数据的$k=0$,否则输出文件就超过限制了。

于是我们在新图上跑个$dp$就行辣

  1. #include<cstdio>
  2. #include<iostream>
  3. using namespace std;
  4. #define N 10000005
  5. const int mod=1e9+;
  6. char fr1[]={'A','C','G','T'},s[N];
  7. int n,k,fr2[],now[N],st[N],tp,ans;
  8. int nxt[N][],fa[N],len[N],ed,last,rt[N],f[N];
  9. void dfs(int tp,int x){//k=1时用dfs找每个子串并输出
  10. st[tp]=x; puts(s+); ++ans;
  11. for(;now[tp]<;++now[tp]){
  12. if(nxt[x][now[tp]]){
  13. s[tp+]=fr1[now[tp]];
  14. now[tp+]=;
  15. dfs(tp+,nxt[x][now[tp]]);
  16. s[tp+]=;
  17. }
  18. }
  19. }
  20. void dp(int tp,int x){//k=0时直接dp,应对大数据
  21. if(f[x]>) return;
  22. f[x]=;
  23. for(;now[tp]<;++now[tp]){
  24. if(nxt[x][now[tp]]){
  25. dp(tp+,nxt[x][now[tp]]);
  26. now[tp+]=;
  27. f[x]=(f[x]+f[nxt[x][now[tp]]])%mod;
  28. }
  29. }
  30. }
  31. struct sam{//裸裸的后缀自动机
  32. void init(int x){
  33. last=rt[x]=++ed; char c=getchar();
  34. while(c<'A'||'T'<c) c=getchar();
  35. while(c!='\n') add(fr2[c],x),c=getchar();
  36. }
  37. void add(int c,int x){
  38. int q,p=last; len[last=++ed]=len[p]+;
  39. for(;p&&!nxt[p][c];p=fa[p]) nxt[p][c]=ed;
  40. if(!p) fa[ed]=rt[x];
  41. else{
  42. q=nxt[p][c];
  43. if(len[q]==len[p]+) fa[ed]=q;
  44. else{
  45. len[++ed]=len[p]+;
  46. for(int k=;k<;++k) nxt[ed][k]=nxt[q][k];
  47. fa[ed]=fa[q]; fa[q]=fa[ed-]=ed;
  48. for(;nxt[p][c]==q;p=fa[p]) nxt[p][c]=ed;
  49. }
  50. }
  51. }
  52. }S;
  53.  
  54. int main(){
  55. freopen("copy.in","r",stdin);
  56. freopen("copy.out","w",stdout);
  57. fr2['A']=;fr2['C']=;fr2['G']=;fr2['T']=;
  58. scanf("%d",&n);
  59. for(int i=;i<=n;++i) S.init(i);
  60. for(int i=n-;i;--i)
  61. for(int j=rt[i];j!=rt[i+];++j)
  62. for(int c=;c<;++c)
  63. if(!nxt[j][c]) nxt[j][c]=nxt[rt[i+]][c];//贪心连边
  64. scanf("%d",&k);
  65. if(k) dfs(,rt[]),printf("%d",ans);
  66. else dp(,rt[]),printf("%d",f[rt[]]);
  67. return ;
  68. }

fjwc2019 D1T2 原样输出(后缀自动机+dp)的更多相关文章

  1. 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp

    题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...

  2. 【SPOJ - SUBLEX】Lexicographical Substring Search 【后缀自动机+dp】

    题意 给出一个字符串和q个询问,每个询问给出一个整数k,输出第k大得子串. 分析 建后缀自动机,利用匹配边来解决.设d[v]为从状态v开始有多少不同的路径.这个显然是可以递推出来的.然后对于每个询问, ...

  3. bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP

    2806: [Ctsc2012]Cheat Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 583  Solved: 330[Submit][Statu ...

  4. BZOJ4032[HEOI2015]最短不公共子串——序列自动机+后缀自动机+DP+贪心

    题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...

  5. 【BZOJ3238】差异【后缀自动机+dp】

    题意 分析 这个题目还是很优秀的.sigma(len(Ti)+len(Tj))的值是一定的=n*(n+1)*(n-1)/2.那么关键就是求任意两个后缀的lcp的和了. 我们怎么求两个后缀的lcp?如果 ...

  6. 【SPOJ -NSUBSTR】Substrings 【后缀自动机+dp】

    题意 给出一个字符串,要你找出所有长度的子串分别的最多出现次数. 分析 我们建出后缀自动机,然后预处理出每个状态的cnt,cnt[u]指的是u这个状态的right集合大小.我们设f[len]为长度为l ...

  7. [BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp

    4566: [Haoi2016]找相同字符 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1212  Solved: 694[Submit][Stat ...

  8. 【BZOJ 4199】[Noi2015]品酒大会 后缀自动机+DP

    题意 两个长度为$r$的子串相等称为$r$相似,两个$r$相似的权值等于子串开头位置权值乘积,给定字符串和每个位置权值,求$r$相似子串数量和最大权值乘积 对反串建立后缀自动机得到后缀树,后缀树上两个 ...

  9. bzoj 3796: Mushroom追妹纸 AC自动机+后缀自动机+dp

    题目大意: 给定三个字符串s1,s2,s3,求一个字符串w满足: w是s1的子串 w是s2的子串 s3不是w的子串 w的长度应尽可能大 题解: 首先我们可以用AC自动机找出s3在s1,s2中出现的位置 ...

随机推荐

  1. [LeetCode] 414. Third Maximum Number_Easy

    Given a non-empty array of integers, return the third maximum number in this array. If it does not e ...

  2. js模拟栈

    栈:先入后出,后入先出 链表:先入先出,后入后出 下面使用js实现栈 var Stack = (function(){ var items = new WeakMap(); //先入后出,后入先出 c ...

  3. iOS Xcode 用 GitHub 托管项目

    直接在xcode里用Github教程:http://jingyan.baidu.com/article/ab0b5630936ab6c15afa7d1c.html 经过本人尝试之后,发现,使用官网的客 ...

  4. unity3d-游戏实战突出重围,第四天 添加角色

    1:添加unity自带的第一人称角色控制器,命名为hreo 2:添加第三人称角色控制器.这里是添加源文件Sources下面的.如箭头指示:而不是“3rd Person Controller”.并命名为 ...

  5. webapp定位

    <!doctype html> <html> <head> <meta charset="utf-8"> <meta http ...

  6. Linux MySQL数据库文件同步及数据库备份

    Mysql数据库链接 mysql -uroot -p -hdatacenter.jiaofukeyan.com -P33069 1.文件同步 rsync -avz --delete root@(需要同 ...

  7. TP增删改

    增加数据 <?php namespace Home\Controller; use Think\Controller; class IndexController extends Control ...

  8. 数据库所有者 (dbo)

    数据库所有者 (dbo) dbo 是具有在数据库中执行所有活动的暗示性权限的用户.将固定服务器角色 sysadmin 的任何成员都映射到每个数据库内称为 dbo 的一个特殊用户上.另外,由固定服务器角 ...

  9. 001- CreateProcess failed with error 216 (no message available)错误详解

    问题详解 runnerw.exe: CreateProcess failed with error 216 (no message available) 看描述,创建进程失败,应该是main这个入口文 ...

  10. django后台的制作

    参考:http://zengestudy.blog.51cto.com/1702365/1902660 http://www.cnblogs.com/fnng/p/3737964.html 实现与后台 ...