题意:在一个字符串里面找最长的[A][B][A]子串,其中[A][B]是回文串,[A]和[B]的长度相等

思路:[A][B]是回文串,所以[B][A]也是回文串。先预处理出每个点的最大回文半径Ri,枚举[A][B]的对称轴位置p,那么就是要找最大的一个[B][A]的对称轴位置i,满足i<=p+R[p],i-R[i]<=p。由于p是递增的,先前满足的以后肯定满足,于是可以用set来维护i-R[i]<=p的所有的位置i的集合,并可在logN的时间内得到最大的位置i。

  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; #define X first
#define Y second
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define copy(a, b) memcpy(a, b, sizeof(a)) typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long long ull; //#ifndef ONLINE_JUDGE
void RI(vector<int>&a,int n){a.resize(n);for(int i=;i<n;i++)scanf("%d",&a[i]);}
void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>
void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?:-;
while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>
void print(const T t){cout<<t<<endl;}template<typename F,typename...R>
void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>
void print(T*p, T*q){int d=p<q?:-;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}
//#endif
template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}
template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}
template<typename T>
void V2A(T a[],const vector<T>&b){for(int i=;i<b.size();i++)a[i]=b[i];}
template<typename T>
void A2V(vector<T>&a,const T b[]){for(int i=;i<a.size();i++)a[i]=b[i];} const double PI = acos(-1.0);
const int INF = 1e9 + ;
const double EPS = 1e-8; /* -------------------------------------------------------------------------------- */ const int maxn = 2e5 + ; struct StringHash {
const static unsigned int hack = ;
//const static int maxn = 2e5 + 7;
unsigned long long H[maxn], C[maxn];
void init(int s[], int n) {
for (int i = ; i < n; i ++) {
H[i] = (i? H[i - ] * hack : ) + s[i];
}
C[] = ;
for (int i = ; i <= n; i ++) C[i] = C[i - ] * hack;
}
unsigned long long get(int L, int R) {
return H[R] - (L? H[L - ] * C[R - L + ] : );
}
} ;
StringHash hsh, hshrev;
vector<int> G[maxn];
int a[maxn], b[maxn], F[maxn];
set<int> S;
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // ONLINE_JUDGE
int T, n, cas = ;
cin >> T;
while (T --) {
cin >> n;
for (int i = ; i < n; i ++) {
scanf("%d", a + i);
}
hsh.init(a, n);
for (int i = ; i < n; i ++) b[i] = a[n - i - ];
hshrev.init(b, n);
int total = * n - ;
for (int i = ; i < total; i ++) {
int L = i / , R = (i + ) / ;
int minlen = , maxlen = min(L + , n - R);
while (minlen < maxlen) {
int midlen = (minlen + maxlen + ) >> ;
int lpos = L - midlen + , rpos = R + midlen - ;
if (hsh.get(lpos, L) == hshrev.get(n - rpos - , n - R - ))
minlen = midlen;
else maxlen = midlen - ;
}
F[i] = minlen;
}
S.clear();
for (int i = ; i < n; i ++) G[i].clear();
int ans = ;
for (int i = ; i < n - ; i ++) {
G[i - F[ * i + ] + ].pb(i);
}
for (int i = ; i < G[].size(); i ++) S.insert(G[][i]);
for (int i = ; i < total; i += ) {
int L = i / ;
for (int j = ; j < G[L + ].size(); j ++) S.insert(G[L + ][j]);
if (S.size()) {
set<int>::iterator R = S.upper_bound(L + F[i]); R --;
umax(ans, *R - L);
}
}
printf("Case #%d: %d\n", ++ cas, ans * );
} return ;
}

[hdu5371 Hotaru's problem]最大回文半径的更多相关文章

  1. [2015hdu多校联赛补题]hdu5371 Hotaru's problem

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5371 题意:把一个数字串A翻过来(abc翻过来为cba)的操作为-A,我们称A-AA这样的串为N-se ...

  2. Manacher算法求回文半径

    http://wenku.baidu.com/link?url=WFI8QEEfzxng9jGCmWHoKn0JBuHNfhZ-tKTDMux34CeY8UNUwLVPeY5HA3TyoKU2XegX ...

  3. HDU5371 Hotaru's problem

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  4. hdu5371 Hotaru's problem

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission ...

  5. Gym - 101981M:(南京) Mediocre String Problem(回文树+exkmp)

    #include<bits/stdc++.h> #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) using ...

  6. HDU 5371——Hotaru's problem——————【manacher处理回文】

    Hotaru's problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  7. Manacher HDOJ 5371 Hotaru's problem

    题目传送门 /* 题意:求形如(2 3 4) (4 3 2) (2 3 4)的最长长度,即两个重叠一半的回文串 Manacher:比赛看到这题还以为套个模板就行了,因为BC上有道类似的题,自己又学过M ...

  8. BZOJ 2342 回文串-Manacher

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2342 思路:先跑一遍Manacher求出p[i]为每个位置为中心的回文半径,因为双倍回文串 ...

  9. BZOJ 2342 双倍回文(manacher算法)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2342 题意:定义双倍回文串为:串的长度为4的倍数且串的前一半.后一半.串本身均是回文的. ...

随机推荐

  1. niuke---勾股定理

    勾股定理------: 当其中一个数a大于1并且为奇数时即a=2*n+1, 那么另外两个数分别为 b=2*n*n+2*n;   c=b+1; 当a为大于等于4的偶数时,即a=2*n时,那么另外两个数分 ...

  2. Cyclic Nacklace 杭电3746

    CC always becomes very depressed at the end of this month, he has checked his credit card yesterday, ...

  3. skynet启动流程及调用服务

     3.基本原理 3.1启动流程  1.skynet-src/skynet_main.c 这个是main()函数所在,主要就是设置一下lua的环境.默认的配置.打开config配置文件,并修改默认配置. ...

  4. vue-cli目录结构分析

    vue3初始化一个项目,查看其项目结构,会发现比vue2的更加简洁. package.json说明 项目的配置文件,定义了项目的基本信息以及项目的相关包依赖,npm运行命令等,位于项目根目录. scr ...

  5. ASP.NET Core技术研究-全面认识Web服务器Kestrel

    因为IIS不支持跨平台的原因,我们在升级到ASP.NET Core后,会接触到一个新的Web服务器Kestrel.相信大家刚接触这个Kestrel时,会有各种各样的疑问. 今天我们全面认识一下ASP. ...

  6. MySQL笔记总结-DML语言

    DML语言 插入 一.方式一 语法: insert into 表名(字段名,...) values(值,...); 特点: 1.要求值的类型和字段的类型要一致或兼容 2.字段的个数和顺序不一定与原始表 ...

  7. 聊聊Spring Boot Actuator

    概述 在本文中,我们将介绍Spring Boot Actuator.我们将首先介绍基础知识,然后详细讨论Spring Boot 1.x和2.x中的可用内容. 我们将在Spring Boot 1.x中学 ...

  8. (c++ std) 查找 vector 中的元素

    You can use std::find from <algorithm>: std::find(vector.begin(), vector.end(), item) != vecto ...

  9. MySQL系列(二)

    查看\创建\使用\删除 数据库 用户管理及授权实战 局域网远程连接法 查看\创建\使用\删除\清空\修改 数据库表(是否可空,默认值,主键,自增,外键) 表内容的增删改查 where条件.通配符_%. ...

  10. Libra教程之:运行自定义move modules

    文章目录 简介 创建Move modules 启动本地网络 创建账号并送测试币 编译Move Module 发布编译好的Module 创建交易脚本 编译编译脚本 执行脚本 简介 因为Libra和Mov ...