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=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
int s[N], st[N], en[N], rnk[N], ht[N], sa[N], f[][N], Log[N], t1[N], t2[N], c[N], bel[N], dp[N][];
bool vis[N][];
char tmp[N];
int n, m; void getsa() {
int *x = t1, *y = t2, m = , i;
for (i = ; i <= m; ++i) c[i] = ;
for (i = ; i <= n; ++i) x[i] = s[i], c[x[i]] ++;
for (i = ; i <= m; ++i) c[i] += c[i - ];
for (i = n; i >= ; --i) sa[c[x[i]] --] = i;
for (int k = ; k <= n; k <<= ) {
int p = ;
for (i = n - k + ; i <= n; ++i) y[++p] = i;
for (i = ; i <= n; ++i) if (sa[i] > k) y[++p] = sa[i] - k;
for (i = ; i <= m; ++i) c[i] = ;
for (i = ; i <= n; ++i) c[x[y[i]]] ++;
for (i = ; i <= m; ++i) c[i] += c[i - ];
for (i = n; i >= ; --i) sa[c[x[y[i]]] --] = y[i];
swap(x, y);
p = ;
x[sa[]] = ;
for (i = ; i <= n; ++i)
x[sa[i]] = (y[sa[i]] == y[sa[i - ]] && y[sa[i] + k] == y[sa[i - ] + k]) ? p - : p ++;
if (p > n) break;
m = p;
}
for (int i = ; i <= n; ++i) rnk[sa[i]] = i;
int k = ;
ht[] = ;
for (int i = ; i <= n; ++i) {
if (rnk[i] == ) continue;
if (k) k --;
int j = sa[rnk[i] - ];
while (i + k <= n && j + k <= n && s[i + k] == s[j + k]) k ++;
ht[rnk[i]] = k;
}
Log[] = -;
for (int i = ; i <= n; ++i) Log[i] = Log[i >> ] + ;
for (int i = ; i <= n; ++i) f[][i] = ht[i];
for (int j = ; j <= Log[n]; ++j)
for (int i = ; i + ( << j) - <= n; ++i)
f[j][i] = min(f[j - ][i], f[j - ][i + ( << (j - ))]);
}
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 + ];
return min(f[k][l], f[k][r - ( << k) + ]);
}
int getlcp(int x,int y) {
return min(query(x, n - y + ), min(en[bel[x]] - x + , y - st[bel[y]] + ));
}
void End() {
puts("Infinity"); exit();
}
int dfs(int x,int t) {
if (vis[x][t]) End();
if (dp[x][t]) return dp[x][t];
vis[x][t] = ;
if (!t) {
for (int i = ; i <= m; ++i) {
int k = getlcp(x, en[i]), l = en[i] - k + , r = x + k - ;
if (r != en[bel[x]] && l != st[i]) dp[x][t] = max(dp[x][t], k * );
else if (r == en[bel[x]] && l == st[i]) End();
else if (r == en[bel[x]]) dp[x][t] = max(dp[x][t], k * + dfs(l - , ));
else dp[x][t] = max(dp[x][t], k * + dfs(r + , ));
}
}
else {
for (int i = ; i <= m; ++i) {
int k = getlcp(st[i], x), l = x - k + , r = st[i] + k - ;
if (l != st[bel[x]] && r != en[i]) dp[x][t] = max(dp[x][t], k * );
else if (l == st[bel[x]] && r == en[i]) End();
else if (l == st[bel[x]]) dp[x][t] = max(dp[x][t], k * + dfs(r + , ));
else dp[x][t] = max(dp[x][t], k * + dfs(l - , ));
}
}
vis[x][t] = ;
return dp[x][t];
}
int main() {
m = read();
for (int i = ; i <= m; ++i) {
scanf("%s", tmp + );
int len = strlen(tmp + );
st[i] = n + ;
for (int j = ; j <= len; ++j) s[++n] = tmp[j] - 'a' + , bel[n] = i;
en[i] = n;
}
for (int i = ; i <= n; ++i) s[i + n] = s[n - i + ];
n <<= ;
getsa();
int ans = ;
for (int i = ; i <= m; ++i)
ans = max(ans, max(dfs(st[i], ), dfs(en[i], )));
for (int i = ; i <= m; ++i) {
for (int j = st[i]; j <= en[i]; ++j) {
int k = getlcp(j, j), l = j - k + , r = j + k - ;
if (l != st[i] && r != en[i]) ans = max(ans, k * - );
else if (l == st[i] && r == en[i]) End();
else if (l == st[i]) ans = max(ans, k * - + dfs(r + , ));
else ans = max(ans, k * - + dfs(l - , ));
}
for (int j = st[i]; j < en[i]; ++j) {
int k = getlcp(j + , j), l = j - k + , r = j + k; // r = j + 1 + k - 1 !!!
if (l != st[i] && r != en[i]) ans = max(ans, k * );
else if (l == st[i] && r == en[i]) End();
else if (l == st[i]) ans = max(ans, k * + dfs(r + , ));
else ans = max(ans, k * + dfs(l - , ));
}
}
cout << ans;
return ;
}

P3900 [湖南集训]图样图森破的更多相关文章

  1. BZOJ3654 : 图样图森破

    考虑枚举回文中心,然后向两边扩展,当匹配到当前串的边界的时候,枚举下一个串接上. 这个过程可以通过记忆化搜索来完成,设: $f[i][0]$表示对于$i$这个位置,$[i,串结尾]$等待匹配的最长回文 ...

  2. Bzoj 3654 图样图森波 题解

    3654: 图样图森破 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 123  Solved: 66[Submit][Status][Discuss] ...

  3. 主席树 || 可持久化线段树 || BZOJ 3653: 谈笑风生 || Luogu P3899 [湖南集训]谈笑风生

    题面:P3899 [湖南集训]谈笑风生 题解: 我很喜欢这道题. 因为A是给定的,所以实质是求二元组的个数.我们以A(即给定的P)作为基点寻找答案,那么情况分两类.一种是B为A的父亲,另一种是A为B的 ...

  4. bzoj 3653 [湖南集训]谈笑风生

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

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

    传送门 nmyzd,mgdhls,bnmbzdgdnlql,a,wgttxfs 对于一个点\(a\),点\(b\)只有可能是他的祖先或者在\(a\)子树里 如果点\(b\)是\(a\)祖先,那么答案为 ...

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

    题意 题目链接 Sol 线段树合并板子题,目前我看到两种写法,分别是这样的. 前一种每次需要新建一个节点,空间是\(O(4nlogn)\) 后者不需要新建,空间是\(O(nlogn)\)(面向数据算空 ...

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

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3653 https://www.luogu.org/problemnew/show/P38 ...

  8. LG3898 [湖南集训]大新闻

    题意 题目描述 **记者弄了个大新闻,这个新闻是一个在 [0,n) 内等概率随机选择的整数,记其为 x.为了尽可能消除这个大新闻对公众造成的不良印象,我们需要在 [0,n)内找到某一个整数 y,使得 ...

  9. 【洛谷 P3899】 [湖南集训]谈笑风生 (主席树)

    题目链接 容易发现\(a,b,c\)肯定是在一条直链上的. 定义\(size(u)\)表示以\(u\)为根的子树大小(不包括\(u\)) 分两种情况, 1.\(b\)是\(a\)的祖先,对答案的贡献是 ...

随机推荐

  1. [翻译] PJR Signature View

    PJR Signature View https://github.com/paritsohraval100/PJRSignatureDemo It is a UIView subclass by w ...

  2. Fiddler下Firefox提示“您的连接并不安全”的解决办法

    一.版本信息 Firefox 最新版本V46.0.1 Fiddler 最新版本V4.6.2.3 二.错误信息 开启fiddlers的https协议捕获的方法,百度上可以查到不再赘述,直接放张图(Too ...

  3. spring-boot-jpa 自定义查询工具类

    1.pom文件中添加如下配置 <dependency> <groupId>org.springframework.boot</groupId> <artifa ...

  4. 021.15 IO流 其他流

    IO包中的其他类操作基本数据类型:DataInputStream与DataOutputStream操作字节数组:ByteArrayInputStream与ByteArrayOutputStream操作 ...

  5. 【问题记录】python 函数 传入一个对象返回一个对象值得注意

    写了一个函数,这个函数接收一个参数,在函数里面判断这个参数是否为None或者不合法状态, 如果处于不合法状态,则创建一个对象返回, 如果合法直接返回 代码示例如下: def get_mq_connec ...

  6. Python中网络编程对 listen 函数的理解

    listen函数的第一个参数时SOCKET类型的,该函数的作用是在这个SOCKET句柄上建立监听,至于有没有客户端连接进来,就需要accept函数去进行检查了,accept函数的第一个参数也是SOCK ...

  7. BZOJ 1040 骑士 基环树 树形DP

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1040 题目大意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫 ...

  8. codeforces 293E Close Vertices

    题目链接 正解:点分治+树状数组. 点分治板子题,直接点分以后按照$w$排序,扫指针的时候把$w$合法的路径以$l$为下标加入树状数组统计就行了. 写这道题只是想看看我要写多久..事实证明我确实是老年 ...

  9. easyui 对form扩展

    功能描述 easyui 中  combobox 多选赋值方法如下: $('#cbx').combobox('setValues', ['01','02']) 然而,业务中是以  “01,02” 的形式 ...

  10. 1031. [JSOI2007]字符加密【后缀数组】

    Description 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法 :把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作 ...