P3900 [湖南集训]图样图森破

链接

分析:

  感觉像个暴力。

  可以枚举回文串的回文中心,即枚举一个串,枚举一个串的位置作为回文中心,然后求出这个串内的回文串的长度。

  此时如果回文串两端都没有到这个串的端点,那么以这个点作为回文中心的长度就直接算出来了。

  如果回文串的长度刚好是这个串的长度,那么INF。

  如果回文串一侧到了端点,那么枚举所有串,看看能否加到另一侧,来构成回文串。此过程记忆化搜索即可。

  复杂度$O(nL \log nL)$

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;inline int read() {int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
}const int N = 200005;
int s[N], st[N], en[N], rnk[N], ht[N], sa[N], f[20][N], Log[N], t1[N], t2[N], c[N], bel[N], dp[N][2];
bool vis[N][2];
char tmp[N];
int n, m;void getsa() {int *x = t1, *y = t2, m = 26, i;for (i = 1; i <= m; ++i) c[i] = 0;for (i = 1; i <= n; ++i) x[i] = s[i], c[x[i]] ++;for (i = 1; i <= m; ++i) c[i] += c[i - 1];for (i = n; i >= 1; --i) sa[c[x[i]] --] = i;for (int k = 1; k <= n; k <<= 1) {int p = 0;for (i = n - k + 1; i <= n; ++i) y[++p] = i;for (i = 1; i <= n; ++i) if (sa[i] > k) y[++p] = sa[i] - k;for (i = 1; i <= m; ++i) c[i] = 0;for (i = 1; i <= n; ++i) c[x[y[i]]] ++;for (i = 1; i <= m; ++i) c[i] += c[i - 1];for (i = n; i >= 1; --i) sa[c[x[y[i]]] --] = y[i];swap(x, y);p = 2;x[sa[1]] = 1;for (i = 2; i <= n; ++i) x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k]) ? p - 1 : p ++;if (p > n) break;m = p;}for (int i = 1; i <= n; ++i) rnk[sa[i]] = i;int k = 0;ht[1] = 0;for (int i = 1; i <= n; ++i) {if (rnk[i] == 1) continue;if (k) k --;int j = sa[rnk[i] - 1];while (i + k <= n && j + k <= n && s[i + k] == s[j + k]) k ++;ht[rnk[i]] = k;}Log[0] = -1;for (int i = 1; i <= n; ++i) Log[i] = Log[i >> 1] + 1;for (int i = 1; i <= n; ++i) f[0][i] = ht[i];for (int j = 1; j <= Log[n]; ++j) for (int i = 1; i + (1 << j) - 1 <= n; ++i) f[j][i] = min(f[j - 1][i], f[j - 1][i + (1 << (j - 1))]);
}
int query(int l,int r) {if (l == r) return 1e9;l = rnk[l], r = rnk[r];if (l > r) swap(l, r);l ++;int k = Log[r - l + 1];return min(f[k][l], f[k][r - (1 << k) + 1]);
}
int getlcp(int x,int y) {return min(query(x, n - y + 1), min(en[bel[x]] - x + 1, y - st[bel[y]] + 1));
}
void End() {puts("Infinity"); exit(0);
}
int dfs(int x,int t) {if (vis[x][t]) End();if (dp[x][t]) return dp[x][t];vis[x][t] = 1;if (!t) {for (int i = 1; i <= m; ++i) {int k = getlcp(x, en[i]), l = en[i] - k + 1, r = x + k - 1;if (r != en[bel[x]] && l != st[i]) dp[x][t] = max(dp[x][t], k * 2);else if (r == en[bel[x]] && l == st[i]) End();else if (r == en[bel[x]]) dp[x][t] = max(dp[x][t], k * 2 + dfs(l - 1, 1));else dp[x][t] = max(dp[x][t], k * 2 + dfs(r + 1, 0));}}else {for (int i = 1; i <= m; ++i) {int k = getlcp(st[i], x), l = x - k + 1, r = st[i] + k - 1;if (l != st[bel[x]] && r != en[i]) dp[x][t] = max(dp[x][t], k * 2);else if (l == st[bel[x]] && r == en[i]) End();else if (l == st[bel[x]]) dp[x][t] = max(dp[x][t], k * 2 + dfs(r + 1, 0));else dp[x][t] = max(dp[x][t], k * 2 + dfs(l - 1, 1));}}vis[x][t] = 0;return dp[x][t];
}
int main() {m = read();for (int i = 1; i <= m; ++i) {scanf("%s", tmp + 1);int len = strlen(tmp + 1);st[i] = n + 1;for (int j = 1; j <= len; ++j) s[++n] = tmp[j] - 'a' + 1, bel[n] = i;en[i] = n;}for (int i = 1; i <= n; ++i) s[i + n] = s[n - i + 1];n <<= 1;getsa();int ans = 0;for (int i = 1; i <= m; ++i) ans = max(ans, max(dfs(st[i], 0), dfs(en[i], 1)));for (int i = 1; i <= m; ++i) {for (int j = st[i]; j <= en[i]; ++j) {int k = getlcp(j, j), l = j - k + 1, r = j + k - 1;if (l != st[i] && r != en[i]) ans = max(ans, k * 2 - 1);else if (l == st[i] && r == en[i]) End();else if (l == st[i]) ans = max(ans, k * 2 - 1 + dfs(r + 1, 0));else ans = max(ans, k * 2 - 1 + dfs(l - 1, 1));}for (int j = st[i]; j < en[i]; ++j) {int k = getlcp(j + 1, j), l = j - k + 1, r = j + k; // r = j + 1 + k - 1 !!!if (l != st[i] && r != en[i]) ans = max(ans, k * 2);else if (l == st[i] && r == en[i]) End();else if (l == st[i]) ans = max(ans, k * 2 + dfs(r + 1, 0));else ans = max(ans, k * 2 + dfs(l - 1, 1));}}cout << ans;return 0;
}

转载于:https://www.cnblogs.com/mjtcn/p/10466434.html

P3900 [湖南集训]图样图森破相关推荐

  1. 洛谷 - P3899 [湖南集训]谈笑风生(dfs序+主席树/二维数点)

    题目链接:点击查看 题目大意:设 TTT 为一棵有根树,我们做如下的定义: 设 aaa 和 bbb 为 TTT 中的两个不同节点.如果 aaa 是 bbb 的祖先,那么称"aaa 比 bbb ...

  2. P3899 [湖南集训]谈笑风生(线段树合并)

    P3899 [湖南集训]谈笑风生 给定一颗以111号节点为根的树,如果a≠ba \neq ba​=b,且aaa是bbb的祖先,则aaa比bbb更厉害,如果a≠ba \neq ba​=b,且dis( ...

  3. P3899 [湖南集训]谈笑风生

    P3899 [湖南集训]谈笑风生 题目描述 Solution 我们考虑离线询问,将询问放在相对应的子树ppp中计算答案. 显然a,b,ca,b,ca,b,c的位置关系有两种情况: bbb是aaa的祖先 ...

  4. P3899 [湖南集训]更为厉害(线段树合并、长链剖分、二维数点)

    P3899 [湖南集训]更为厉害 若 deepb<deepa\text{deep}_b<\text{deep}_adeepb​<deepa​:c 在点 a 的子树中,根据乘法原理计算 ...

  5. OI生涯回忆录(Part7:至高一湖南集训Day3)

    (卅一)联赛惨案 NOIP结束了,自然我是要回班上课的. 王晓光这边说着尽量在沟通让我和李佳实尽快脱产,然而并不知道什么时候能办完.... 转过来这个周中就开始了各种山寨数据的测试,学军自己出的.杭二 ...

  6. [湖南集训]更为厉害 树上主席树-以树深度为下下标建立主席树

    题意题解: 首先对于树上某个点a来说,假设点b是a的祖先(也就是在a的上面),那么答案很好计算,也就是min(k,dep[a]−1)∗(size[a]−1)min(k,dep[a]-1)*(size[ ...

  7. P3899 [湖南集训]谈笑风生 主席树解决二维数点

    传送门 文章目录 题意: 思路: 题意: 思路: 由于a,ba,ba,b都比ccc厉害,那么a,ba,ba,b一定是某个是某个的祖先.那么就分为两种情况了: (1)(1)(1) bbb在aaa上面,约 ...

  8. [湖南集训] 谈笑风生

    题意: 设 T 为一棵有根树,我们做如下的定义: • 设 a 和 b 为 T 中的两个不同节点.如果 a 是 b 的祖先,那么称"a 比 b 不知道高明到哪里去了". • 设 a ...

  9. 【清华夏令营2016模拟5.31】图森破

    题目 Description 小火车励志成为一名辣鸡出题人,但是要成为一名辣鸡出题人,代码必须跑得比谁都快,这样就能把他们都卡常数了!为了锻炼自己,他找到了一位长者--罗长者,罗长者说:"你 ...

  10. 题解 [校内测试]图森破

    题意 设 f(n)f(n)f(n) 为满足以下条件的字符串个数: 串长为 SSS,字符集为 [0,9][0,9][0,9]. 设 sufisuf_isufi​ 为第 iii 个字符对应的后缀在最后补 ...

最新文章

  1. Laravel-Action 对代码的改造
  2. 基于Redis优化购物车 - 添加商品
  3. 掌握这 25 条小贴士,快速提升数据可视化能力!
  4. HierarchicalDataTemplate中的ContextMenu的Command绑定
  5. html工作界面抽象吗,WEB界面设计五种特征-网页设计,HTML/CSS
  6. eclipse打开就闪退怎么办?
  7. awgn信道matlab,AWGN信道下数字通信系统的蒙特卡洛仿真(基于matlab).doc
  8. 网页音乐视频不让下载怎么办
  9. Ubuntu常用软件安装,持续更新中。。。
  10. 计算机网络基础(TCP/IP)
  11. 免费获取对方ip地址PHP源码
  12. 手把手教你处理 JS 逆向之图片伪装
  13. 将C语言的字符串转为OC的字符串
  14. [4G/5G/6G专题基础-155]: 5G 3GPP高精确室内定位原理、AI方案概述
  15. Latex CJK,tex使用中文
  16. java全栈系列之JavaSE-面向对象(类与对象的创建)032
  17. centos GPU tensorflow pytorch 深度学习 环境搭建
  18. Python+Matplotlib绘制曲线并实现鼠标跟随的放大镜
  19. “.plt“文件转png格式图片简写
  20. 数学建模笔记——插值拟合模型(二)

热门文章

  1. 电脑里删除的文件怎么恢复,数据恢复方法大全
  2. 最常用的计算机色彩表示方法——RGB模式与CMYK模式
  3. win7和win10对于wifi共享的不同
  4. app上架华为应用市场流程
  5. 京东云首次发布数智供应链全景图 锚定产业数字化新赛道
  6. 深度解析DDD中台和微服务设计 | 留言送书
  7. 免苹果开发者账号申请iOS上架及证书打包ipa测试(2022最新详解)
  8. Word文件带密码如何解除?
  9. Calendar计算两个日期相差几个月
  10. littlevgl抗锯齿_「VGL」Littlevgl 显示汉字 - seo实验室