传送门


当我打开Luogu题解发现这道题可以Hash+贪心的时候我的内心是崩溃的……

但是看到这道题不都应该认为这是一道PAM的练手好题么……

首先把原字符串重排为\(s_1s_ks_2s_{k-1}s_3s_{k-2}...\)之后,我们不难发现:在一种对原串的回文划分中,对应的一对字符串在新的字符串上对应了一个长度为偶数的回文串。

那么设\(dp_i\)表示将新字符串的长度为\(i\)的前缀划分为若干个长度为偶数的回文串,最多划分多少份。在回文树上可以进行转移。使用“一个长度为\(n\)串的回文后缀形成\(log n\)个等差数列”的结论将DP优化为\(O(nlogn)\)的复杂度。具体步骤可以看yyb的CF932G Palindrome Partition的题解

最后我们取\(\max(dp_i + [i < L](2 \mid i))\)作为答案。

注意悠着点开数组……

#include<bits/stdc++.h>
//this code is written by Itst
using namespace std; const int _ = 1e6 + 7;
char s[_] , tmp[_]; int dp[_] , pre[_] , T , L;
namespace PAM{
int trans[_][26] , fa[_] , len[_] , diff[_] , anc[_];
int cnt , lst; #define clr(x) memset(x , 0 , sizeof(x[0]) * (cnt + 1))
void init(){
clr(trans); clr(fa); clr(len); clr(diff); clr(anc);
lst = 0; cnt = 1; len[1] = -1; fa[0] = fa[1] = 1;
} void extend(int x){
int p = lst;
while(s[x - len[p] - 1] != s[x]) p = fa[p];
if(trans[p][s[x] - 'a'])
return (void)(lst = trans[p][s[x] - 'a']);
int k = ++cnt , q = fa[p];
while(s[x - len[q] - 1] != s[x]) q = fa[q];
fa[k] = trans[q][s[x] - 'a']; trans[p][s[x] - 'a'] = k;
len[k] = len[p] + 2; lst = k;
diff[k] = len[k] - len[fa[k]]; anc[k] = diff[k] == diff[fa[k]] ? anc[fa[k]] : k;
}
}
using namespace PAM; int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
for(scanf("%d" , &T) ; T ; --T){
memset(dp , -0x3f , sizeof(dp)); dp[0] = 0;
memset(pre , -0x3f , sizeof(pre));
scanf("%s" , tmp + 1); L = strlen(tmp + 1);
int cnt = 0;
for(int i = 1 , j = L ; i <= j ; (i + j - L) & 1 ? ++i : --j)
s[++cnt] = (i + j - L) & 1 ? tmp[i] : tmp[j];
init();
for(int i = 1 ; i <= L ; ++i){
extend(i);
for(int t = lst ; t ; t = fa[anc[t]]){
if(anc[t] != t)
pre[t] = max(pre[fa[t]] , dp[i - len[anc[t]]]);
else pre[t] = dp[i - len[anc[t]]];
if(!(i & 1))
dp[i] = max(dp[i] , pre[t]);
}
dp[i] += 2;
}
int MAX = 0;
for(int i = 0 ; i <= L ; i += 2)
MAX = max(MAX , dp[i] + (i < L));
cout << MAX << endl;
}
return 0;
}

最新文章

  1. 【学习笔记】C语言之词法规则
  2. 51nod1185(wythoff+高精度)
  3. Hibernate内测总结
  4. function方法中this的用法
  5. 介绍开源的.net通信框架NetworkComms框架 源码分析(十七 ) ConnectionSendClose
  6. Security &#187; Authorization &#187; 基于角色的授权
  7. Mac terminal 解压压缩
  8. php或js判断网站访问者来自手机或者pc
  9. 涂抹Oracle笔记2:数据库的连接-启动-关闭
  10. 多线程并发编程之显示锁ReentrantLock和读写锁
  11. raise()函数
  12. Rookey.Frame v1.0 视频教程发布了
  13. 搭建Jetbrains家族IDE授权服务器
  14. @DateTimeFormat(pattern = &quot;yyyy-MM-dd HH:mm:ss&quot;) 前台request 获取body的格式是正确的 (2018-03-23 16:44:22) 但是Java 后台却格式化成了yyyy-MM-dd的格式 巨坑(@InitBinder搞得贵)
  15. 07 zabbix之map拓扑标签中macro应用
  16. MongoDB win10 安装教程(zip)
  17. V8源码边缘试探-黑魔法指针偏移
  18. day05(Object,tostring(),equals(),System,Date,SimpleDateFormat,拆装箱,正则表达式)
  19. Hibernate的查询方式汇总
  20. mongodb,redis,mysql的区别和具体应用场景

热门文章

  1. BZOJ 3435: [Wc2014]紫荆花之恋
  2. mysql upper() 函数
  3. plsql 如何导入excel数据?
  4. 再见,Eclipse。
  5. python 操作 elasticsearch-7.0.2 遇到的问题
  6. 解决Bootstrap标签页(Tab)插件切换echarts不显示问题
  7. NamedPipeStream的使用案例
  8. sqlite数据库使用具体案例以及mysqlite.db数据库
  9. uploadifive 1.1.2 动态传参
  10. RedisHelper Redis帮助类