fjwc2019 D1T2 原样输出(后缀自动机+dp)
暴力对每个串建后缀自动机,然后暴力枚举每个自动机的子串。可以拿到部分分。
然鹅我们可以把每个后缀自动机连起来。
我们知道,后缀自动机是用最少的点(空间)表示出一个串的所有子串。
那么我们为啥不在后缀自动机上直接跑dp呢?于是我们把它们连起来。
复制一段ppt:
可以怎么拼呢?
我们考虑如何判断一个字符串是否是可能的输出文件
显然我们可以贪心地匹配,每次拿起一个输入串,一直匹配到不能再加字符了才放下,这样一定是正确的
于是我们可以告诉自动机如果失配了要往哪走
比如有一个节点没有C的转移边,那么就要向之后第一个包含字符C的字符串的后缀自动机接受字符串C的节点连一条C的转移边
当然如果这样的字符串不存在就不需要连边
把自动机建起来后
对于$k=1$的情况,直接dfs搞定
但是面对大数据,dfs显然是会TLE的鸭
但是仔细一看
对于 100% 的数据,保证输入文件大小不超过 1MB ,保证输出文件大小不超过 200MB 。
显然大数据的$k=0$,否则输出文件就超过限制了。
于是我们在新图上跑个$dp$就行辣
#include<cstdio>
#include<iostream>
using namespace std;
#define N 10000005
const int mod=1e9+;
char fr1[]={'A','C','G','T'},s[N];
int n,k,fr2[],now[N],st[N],tp,ans;
int nxt[N][],fa[N],len[N],ed,last,rt[N],f[N];
void dfs(int tp,int x){//k=1时用dfs找每个子串并输出
st[tp]=x; puts(s+); ++ans;
for(;now[tp]<;++now[tp]){
if(nxt[x][now[tp]]){
s[tp+]=fr1[now[tp]];
now[tp+]=;
dfs(tp+,nxt[x][now[tp]]);
s[tp+]=;
}
}
}
void dp(int tp,int x){//k=0时直接dp,应对大数据
if(f[x]>) return;
f[x]=;
for(;now[tp]<;++now[tp]){
if(nxt[x][now[tp]]){
dp(tp+,nxt[x][now[tp]]);
now[tp+]=;
f[x]=(f[x]+f[nxt[x][now[tp]]])%mod;
}
}
}
struct sam{//裸裸的后缀自动机
void init(int x){
last=rt[x]=++ed; char c=getchar();
while(c<'A'||'T'<c) c=getchar();
while(c!='\n') add(fr2[c],x),c=getchar();
}
void add(int c,int x){
int q,p=last; len[last=++ed]=len[p]+;
for(;p&&!nxt[p][c];p=fa[p]) nxt[p][c]=ed;
if(!p) fa[ed]=rt[x];
else{
q=nxt[p][c];
if(len[q]==len[p]+) fa[ed]=q;
else{
len[++ed]=len[p]+;
for(int k=;k<;++k) nxt[ed][k]=nxt[q][k];
fa[ed]=fa[q]; fa[q]=fa[ed-]=ed;
for(;nxt[p][c]==q;p=fa[p]) nxt[p][c]=ed;
}
}
}
}S; int main(){
freopen("copy.in","r",stdin);
freopen("copy.out","w",stdout);
fr2['A']=;fr2['C']=;fr2['G']=;fr2['T']=;
scanf("%d",&n);
for(int i=;i<=n;++i) S.init(i);
for(int i=n-;i;--i)
for(int j=rt[i];j!=rt[i+];++j)
for(int c=;c<;++c)
if(!nxt[j][c]) nxt[j][c]=nxt[rt[i+]][c];//贪心连边
scanf("%d",&k);
if(k) dfs(,rt[]),printf("%d",ans);
else dp(,rt[]),printf("%d",f[rt[]]);
return ;
}
fjwc2019 D1T2 原样输出(后缀自动机+dp)的更多相关文章
- 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp
题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...
- 【SPOJ - SUBLEX】Lexicographical Substring Search 【后缀自动机+dp】
题意 给出一个字符串和q个询问,每个询问给出一个整数k,输出第k大得子串. 分析 建后缀自动机,利用匹配边来解决.设d[v]为从状态v开始有多少不同的路径.这个显然是可以递推出来的.然后对于每个询问, ...
- bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP
2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 583 Solved: 330[Submit][Statu ...
- BZOJ4032[HEOI2015]最短不公共子串——序列自动机+后缀自动机+DP+贪心
题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...
- 【BZOJ3238】差异【后缀自动机+dp】
题意 分析 这个题目还是很优秀的.sigma(len(Ti)+len(Tj))的值是一定的=n*(n+1)*(n-1)/2.那么关键就是求任意两个后缀的lcp的和了. 我们怎么求两个后缀的lcp?如果 ...
- 【SPOJ -NSUBSTR】Substrings 【后缀自动机+dp】
题意 给出一个字符串,要你找出所有长度的子串分别的最多出现次数. 分析 我们建出后缀自动机,然后预处理出每个状态的cnt,cnt[u]指的是u这个状态的right集合大小.我们设f[len]为长度为l ...
- [BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1212 Solved: 694[Submit][Stat ...
- 【BZOJ 4199】[Noi2015]品酒大会 后缀自动机+DP
题意 两个长度为$r$的子串相等称为$r$相似,两个$r$相似的权值等于子串开头位置权值乘积,给定字符串和每个位置权值,求$r$相似子串数量和最大权值乘积 对反串建立后缀自动机得到后缀树,后缀树上两个 ...
- bzoj 3796: Mushroom追妹纸 AC自动机+后缀自动机+dp
题目大意: 给定三个字符串s1,s2,s3,求一个字符串w满足: w是s1的子串 w是s2的子串 s3不是w的子串 w的长度应尽可能大 题解: 首先我们可以用AC自动机找出s3在s1,s2中出现的位置 ...
随机推荐
- API 接口自动化测试框架
转自: https://testerhome.com/topics/3455 前言 接口自动化逐渐成为各大公司投入产出最高的测试技术.但是如何在版本迅速迭代过程中提高接口自动化的测试效率,仍然是大部分 ...
- 数据分析与挖掘 - R语言:KNN算法
一个简单的例子!环境:CentOS6.5Hadoop集群.Hive.R.RHive,具体安装及调试方法见博客内文档. KNN算法步骤:需对所有样本点(已知分类+未知分类)进行归一化处理.然后,对未知分 ...
- python-数据
python基本数据类型 数字 整型 int 123 浮点型 float 3.2 布尔型 bool True/False 复数 complex 1+1j 组 序列 字符串 str "hell ...
- 开源unittest测试报告源码BSTestRunner.py
开源BSTestRunner 生成HTML测试报告源码: 保存代码到BSTestRunner.py 配合Unittest使用,很完美. python2: """ A Te ...
- shell编程:if语句
条件判断式的两边的空格不能生
- jq文件上传及下载
一.使用jquery.form.js上传文件 jquery.form.js获取地址:https://pan.baidu.com/s/1nSdfkCt25Rc5cHMFJRVcUQ 提取码: sbmt ...
- D. Duff in Beach
题意 数字串a[0---n-1], 通过不断的重复组成了 b[0,---l-1]l<10^18, 让你计算出 长度小于等于k的最长非递减子序列,满足,取得第 i 个取得是 L1 第i+1个取得 ...
- 【转】python3实现自动化框架robotframework
由于python2只更新到2020年,python3是未来的主流,为了适应技术的变化python3实现robotframework是迟早的事 1.下载最新版本的python3.7,可根据自己电脑的位数 ...
- Linux Firewall 开启与关闭 以及sudo 设置
Linux 系统下,普通用户经常需要使用root 用户的权限,所以要经常切换到root用户,比较麻烦,因此可以给普通用户添加root 权限,需要在常规命令前面加上sudo 切换到root vi /e ...
- Failed to start component [StandardEngine[Tomcat].StandardHost[localhost]]
1.问题场景描述:一个maven项目启动时候,偶尔会报tomcat的这个错误(如图:) 随机报错,有时频率很高,要一直重新启动很多次可能还是启动不了,有时不报错.. 2.解决过程:网上各种寻找解决办法 ...