题意:
给你一串字符串,每个字符都有一个权值,要求把这个字符串在某点分开,使之成为两个单独的字符串
如果这两个子串某一个是回文串,则权值为那一个串所有的字符权值和
若不是回文串,则权值为0
解析:
先用Manacher算法求出以每个字母为中心的回文串的长度,并计算该字符串的前缀价值和。然后枚举切割点,得到两份子串。这样就可以知道每个子串的中心点,然后检查以该子串的中心点作为中心点的回文串的长度,如果长度等于该子串的长度,那么就加上该子串的价值。然后和最优价值比较就行了。
注意只有一个字符时输出0
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> #include <cmath> #define rap(i, a, n) for(int i=a; i<=n; i++) #define rep(i, a, n) for(int i=a; i<n; i++) #define lap(i, a, n) for(int i=n; i>=a; i--) #define lep(i, a, n) for(int i=n; i>a; i--) #define rd(a) scanf("%d", &a) #define rlld(a) scanf("%lld", &a) #define rc(a) scanf("%c", &a) #define rs(a) scanf("%s", a) #define MOD 2018 #define LL long long #define ULL unsigned long long #define Pair pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define _ ios_base::sync_with_stdio(0),cin.tie(0) //freopen("1.txt", "r", stdin); using namespace std; const int maxn = 500010, INF = 0x7fffffff; char s[maxn], s_new[maxn<<1]; int p[maxn<<1], a[30], sum[maxn]; int init(char *s) { int len = strlen(s); s_new[0] = '$'; s_new[1] = '#'; int j = 2; rep(i, 0, len) { s_new[j++] = s[i]; s_new[j++] = '#'; } s_new[j++] = '