传送门

回文自动机的好题啊

先建一个回文自动机,然后记$dp[i]$表示转移到$i$节点代表的回文串的最少的需要次数

首先肯定2操作越多越好,经过2操作之后的串必定是一个回文串,所以最后的答案肯定是由一个回文串+不断暴力添加得来,那么答案就是$min(ans,dp[i]+n-len[i])$

然后对于一个串$i$,如果它在前面和后面加上一个字母可以形成回文串$j$,则$dp[j]=dp[i]+1$

为啥嘞?我们可以假设在形成$i$的之前一步把这个字母加上去,执行2操作后就可以变成$j$了

然后我们可以fail指针找到最长的回文串$x$满足$len[x]<=len[i]/2$,那么$dp[i]=min(dp[i],dp[x]+1+len[i]/2-len[x])$(先暴力填好一半,剩下的用2操作)

然后可以用队列记录状态,保证转移至有序的

至于怎么找$x$,我们可以直接在建自动机的时候顺便求出来,就是多跳几次。这个看代码好了

 //minamoto
#include<cstring>
#include<cstdio>
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,:;}
const int N=2e5+,M=;
char s[N];int dp[N],len[N],fail[N],ch[N][M];
int trans[N],last,p,q,str[N],tot,ans,n,qu[N];
int val[];
inline int newnode(int x){
len[++tot]=x;memset(ch[tot],,sizeof(ch[tot])*);return tot;
}
inline int getfail(int x,int n){
while(s[n-len[x]-]!=s[n]) x=fail[x];return x;
}
inline void init(){
val['A']=,val['T']=,val['C']=,val['G']=;
s[]=-,fail[]=,last=;
len[]=,len[]=-,tot=;
memset(ch[],,sizeof(int)*),memset(ch[],,sizeof(int)*);
}
void ins(int c,int i){
p=getfail(last,i);
if(!ch[p][c]){
q=newnode(len[p]+);
fail[q]=ch[getfail(fail[p],i)][c];
ch[p][c]=q;
if(len[q]<=) trans[q]=fail[q];
else{
int tmp=trans[p];
while(s[i--len[tmp]]!=s[i]||(len[tmp]+)*>len[q]) tmp=fail[tmp];
trans[q]=ch[tmp][c];
}
}
last=ch[p][c];
// printf("%d\n",last);
}
int main(){
// freopen("testdata.in","r",stdin);
int T;scanf("%d",&T);
while(T--){
scanf("%s",s+);
init(),ans=n=strlen(s+);
for(int i=;i<=n;++i) ins(val[s[i]],i);
for(int i=;i<=tot;++i) dp[i]=len[i];
int h=,t=;qu[++t]=,dp[]=;
while(h<=t){
int u=qu[h++];
for(int i=;i<;++i){
int x=ch[u][i];
if(!x) continue;
dp[x]=dp[u]+;
int y=trans[x];
cmin(dp[x],dp[y]++len[x]/-len[y]);
cmin(ans,dp[x]+n-len[x]);
qu[++t]=x;
}
}
printf("%d\n",ans);
}
return ;
}

最新文章

  1. 2014北邮新生归来赛解题报告d-e
  2. Web前端开发笔试&amp;面试_04
  3. HDU 4081 Qin Shi Huang&#39;s National Road System [次小生成树]
  4. 图解SQL的Join(转摘)
  5. SOA之(5)——REST的SOA(SOA with REST)概念
  6. 这样就算会了PHP么?-5
  7. HNCU1741:算法3-2:行编辑程序
  8. UML 解析
  9. Oracle11g 创建表空间、创建用户、角色授权、导入导出表以及中文字符乱码问题
  10. Java中Calendar.DAY_OF_WEEK、DAY_OF_MONTH需要减一的原因
  11. int指令
  12. 多个页面引用公共的头部 header.html 和尾部 footer.html
  13. vue的事件对象,方法执行
  14. 群等变网络的pytorch实现
  15. CentOS上用Squid搭建HTTP代理小结
  16. jenkins2
  17. Visual Studio 2015 正式版镜像下载(含专业版/企业版KEY)
  18. Unity扩展编辑器一
  19. Java关于数组操作函数
  20. CoCreateInstance(转)

热门文章

  1. Android studio导入第三方类库源码以及jar包
  2. Oracle_Exception_01_The Network Adapter could not establish the connection
  3. 基于zepto使用swipe.js制作轮播图demo
  4. ACM学习历程—FZU2195 检查站点(树形DP || 贪心)
  5. JSONP -- 跨域数据交互协议
  6. [转]SCSS 和 SASS 和 HAML 和CoffeeScript
  7. UOJ#164:【清华集训2015】V
  8. python中如何定义main方法
  9. Send Code to evernote by my specify notebook
  10. Spring之2:Spring Bean动态注册、删除