UVAlive 4975 Manacher+枚举
2017-09-20 15:25
267 查看
题意:
题目链接:https://vjudge.net/problem/UVALive-4975给出一个字符串,求形如XYXY的最长子串长度,其中Y时X的逆字符串。
思路:
一开始没仔细想上来就二分hash,后来发现并不满足二分条件。正解是manacher预处理,然后暴力枚举长度,枚举时有讲究,显然长度一定时4的倍数,然后再看左右两个子串的回文串范围。
代码:
#include <bits/stdc++.h> using namespace std; const int MAXN = 3e5 + 10; int n, l; int len[MAXN << 1]; char a[MAXN], s[MAXN]; int manachar (char *p) { n = strlen (p), l = 0; s[l++] = '@'; s[l++] = '#'; for (int i = 0; i < n; i++) { s[l++] = p[i]; s[l++] = '#'; } s[l++] = '~'; s[l] = 0; //cout << s << endl; int Max = 0, pos = 0, ans = 0; for (int i = 1; i < l; i++) { if (Max > i) { len[i] = min (len[2 * pos - i], Max-i); } else len[i] = 1; while (s[i+len[i]] == s[i-len[i]]) len[i]++; ans = max (ans, len[i]); if (len[i] + i > Max) { Max = len[i]+i; pos = i; } } return ans-1; } int main() { //freopen("in.txt", "r", stdin); int T; scanf("%d", &T); while (T--) { scanf("%s", a); manachar(a); int ans = 0; for (int i = 1; i < l; i += 2) { int x = len[i] - 1; if (x < 4) continue; while (x % 4 != 0) x--; for (; x > ans; x -= 4) { int p1 = i - x / 2, p2 = i + x / 2; if (len[p1] - 1 >= x / 2 && len[p2] - 1 >= x / 2) { ans = x; break; } } } printf("%d\n", ans); } return 0; }
相关文章推荐
- UVALive 4975 Casting Spalls
- uvalive 4975
- UVALive - 4975 Casting Spells Manacher回文串
- UVALive 4975 - Casting Spells Manacher+科学枚举
- UVALive 4975 (LA 4975) Casting Spells Manacher + Set维护
- UVALive - 4975_Casting Spells
- UVALive 4975 Casting Spells
- UVALive 6886 Golf Bot 桶排+剪枝
- UVALive 6652 Game of Throne(一般图最大加权匹配)
- UVALive 6590 Digraphs (DFS找环找通路)
- UVALive 6604 Airport Sort 【归并排序】【逆序数】
- UVALive 6602 Counting Lattice Squares
- UESTC 893&&uvalive 6627 First Date
- UVALive3211 Now or later
- UVALive - 2572 Viva Confetti 极角排序
- UVALive 6833 Miscalculation (模拟)
- POJ 1459 Power Network / HIT 1228 Power Network / UVAlive 2760 Power Network / ZOJ 1734 Power Network / FZU 1161 (网络流,最大流)
- UVALive 6709 - Mosaic 二维线段树
- UVALive 3989 - Ladies' Choice(稳定婚姻匹配)
- UVALive4513 Stammering Aliens(哈希法,后缀数组)