BZOJ 4044 Virus synthesis (回文自动机+dp)
题目大意:
你可以在一个串的开头或者末尾加入一个字符,或者把当前整个串$reverse$,然后接在前面或者后面,求达到目标串需要的最少操作次数
对目标串建出$PAM$
定义$dp[x]$表示当前在回文树的x节点,拼凑出这个节点表示的回文串所需要的最小操作次数
$fa_{x}$表示沿着树边指向它的父亲,$pre_{x}$表示它的$fail$指针
如果它是奇回文串,一定不能被翻转得到,所以开头结尾各需要加上一个字符,$dp[x]=dp[fa_{x}]+2$
如果它是偶回文串,可以被翻转得到
1.要么是在上次翻转之前先添加一个字符,再翻转得到,$dp[x]=dp[fa_{x}]+1$
2.要么是在这次进行翻转,需要保证被翻转的串长度不大于$dep[x]/2$
可以在回文树上倍增跳$pre$,找到$x$的一个长度不大于$dep[x]/2$的回文后缀所在节点$y$
只需要找后缀的情况即可,其他的情况会被合并到情况一里
剩下的部分也要被暴力地填上,那么$dp[x]=dp[y]+dep[x]/2-dep[y]+1$
#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 100100
#define S1 (N1<<1)
#define ll long long
#define uint unsigned int
#define rint register int
#define dd double
#define il inline
#define inf 0x3f3f3f3f
using namespace std; int len,T;
inline int idx(char x)
{
if(x=='A') return ;
if(x=='C') return ;
if(x=='G') return ;
if(x=='T') return ;
}
char str[N1];
int lg[N1];
namespace PAM{
int trs[N1][],pre[N1],dep[N1],fa[N1],dp[N1],la,tot;
int ff[N1][];
void init()
{
tot++;
memset(trs,,tot**),memset(pre,,tot*);
memset(ff,,tot**),memset(fa,,tot*);
memset(dp,,tot*),memset(dep,,tot*);
la=tot=,dep[]=-;pre[]=pre[]=;
}
int chk(char *str,int i,int p){return str[i-dep[p]-]!=str[i]?:;}
void insert(char *str,int i)
{
int p=la,np,fp,c=idx(str[i]);
while(chk(str,i,p)) p=pre[p];
if(!trs[p][c])
{
np=++tot;
dep[np]=dep[p]+;
fp=pre[p];
while(chk(str,i,fp)) fp=pre[fp];
pre[np]=trs[fp][c];
trs[p][c]=np;
fa[np]=p;
}
la=trs[p][c];
}
int solve()
{
int i,j,x,ans=len,de;
ff[][]=ff[][]=ff[][]=ff[][]=;
for(i=;i<=tot;i++) ff[i][]=i,ff[i][]=pre[i];
for(j=;j<=;j++)
for(i=;i<=tot;i++)
ff[i][j]=ff[ ff[i][j-] ][j-];
dp[]=,dp[]=-;
for(i=;i<=tot;i++)
{
x=i;
dp[i]=dp[fa[i]]+((dep[i]&)?:);
if((dep[i]&)) continue;
for(j=lg[dep[i]];j>=;j--)
if(dep[ff[x][j]]>=dep[i]/) x=ff[x][j];
if(dep[x]>dep[i]/) x=pre[x];
dp[i]=min(dp[i],dp[x]++dep[i]/-dep[x]);
ans=min(ans,len-dep[i]+dp[i]);
}
return ans;
}
}; int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%s",str+);
len=strlen(str+);
int i;
for(lg[]=,i=;i<=len;i++) lg[i]=lg[i>>]+;
PAM::init();
for(i=;i<=len;i++) PAM::insert(str,i);
printf("%d\n",PAM::solve());
}
return ;
}
BZOJ 4044 Virus synthesis (回文自动机+dp)的更多相关文章
- bzoj 4044: Virus synthesis 回文自动机
题目大意: 你要用ATGC四个字母用两种操作拼出给定的串: 将其中一个字符放在已有串开头或者结尾 将已有串复制,然后reverse,再接在已有串的头部或者尾部 一开始已有串为空.求最少操作次数. le ...
- bzoj 4044 Virus synthesis - 回文自动机 - 动态规划
题目传送门 需要高级权限的传送门 题目大意 要求用两种操作拼出一个长度为$n$的只包含'A','T','G','C'的字符串 在当前字符串头或字符串结尾添加一个字符 将当前字符串复制,将复制的串翻转, ...
- bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp)
bzoj4044/luoguP4762 [Cerc2014]Virus synthesis(回文自动机+dp) bzoj Luogu 你要用ATGC四个字母用两种操作拼出给定的串: 1.将其中一个字符 ...
- BZOJ 4044 Luogu P4762 [CERC2014]Virus Synthesis (回文自动机、DP)
好难啊..根本不会做..基本上是抄Claris... 题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4044 (luogu) ...
- [BZOJ4044]Virus synthesis 回文自动机的DP
4044: [Cerc2014] Virus synthesis Time Limit: 20 Sec Memory Limit: 128 MB Description Viruses are us ...
- luogu P4762 [CERC2014]Virus synthesis (回文自动机)
大意: 初始有一个空串, 操作(1)在开头或末尾添加一个字符. 操作(2)在开头或末尾添加该串的逆串. 求得到串$S$所需最少操作数. 显然最后一定是由某个偶回文通过添加字符得到的, 那么只需要求出所 ...
- bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp)
bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp) bzoj Luogu 对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一 ...
- bzoj 4044: [Cerc2014] Virus synthesis【回文自动机+dp】
建回文自动机,注意到一个回文串是可以通过一个长度小于等于这个串长度的一半的回文串添上一些字符然后复制得到的,也就是在自动机上向fa走,相当于treedp 每次都走显然会T,记录一个up,指向祖先中最下 ...
- [CERC2014]Virus synthesis【回文自动机+DP】
[CERC2014]Virus synthesis 初始有一个空串,利用下面的操作构造给定串 SS . 1.串开头或末尾加一个字符 2.串开头或末尾加一个该串的逆串 求最小化操作数, \(|S| \l ...
随机推荐
- 利用vue-gird-layout 制作可定制桌面 (二)
添加资源池 根据项目需求 添加, 实例两个数据 { "mainData": [ { "x": 0, "y": 0, "w" ...
- vue组件通信,点击传值,动态传值(父传子,子传父)
转载:https://blog.csdn.net/xr510002594/article/details/83304141 一.父组件传子组件,核心--props 在这里触发 handleClick ...
- 【模板】最大流模板(dinic)
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行 ...
- 微信公众号开发之获取微信用户的openID
(注:openID同一用户同一应用唯一,UnionID同一用户不同应用唯一.不同应用指微信开放平台下的不同用户.) 1. 申请测试号(获得appID.appsecret) 2. 填写服务器配置并验 ...
- 【AIM Tech Round 5 (rated, Div. 1 + Div. 2) B】Unnatural Conditions
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 让a+b的和为100000000...0这样的形式就好了 这样s(a+b)=1<=m就肯定成立了(m>=1) 然后至于s ...
- Makefile错误总结
自己在做嵌入式驱动时,编写makefile文件是犯的错及解决办法 问题1:makefile 3 missing separator.stop: 问题2:Nothing to be done for ' ...
- C#中的DES加密
publicstaticstringEncryptString(string sInputString,string sKey,string sIV) { try { byte[] data =Enc ...
- 洛谷—— P1120 小木棍 [数据加强版]
https://www.luogu.org/problem/show?pid=1120 题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接 ...
- Oracle-定时任务
PLSQL->新建->命令行窗口 --存储过程 create or replace procedure prd_remove_error_data AS BEGIN UPDATE rpt_ ...
- MongoDB 2.6安装
Workaround to install as a service You can manually install 2.6.0 as a service on Windows from an Ad ...