分类大讨论即可
若字符串本身就回文,区间可以任意取,否则,若区间[l,r]合法,那么[ll,rr]满足ll<=l且rr>=r的区间都合法,和[l,r]完全没有交集的区间不合法。
那么一定能找到一个最小的区间必须被所有合法的区间包含,且包含它的皆为合法的区间,找出来就行了。
#include <iostream>
#include <cstdio>
#include <cstring>
#define N 200050
using namespace std;
int a[N],t[N],cur[N],n,pos,ret;
int main() {
bool flag = false;
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=n;i++) t[ a[i] ]++;
for (int i=1;i<=n;i++) if (t[i]&1) {
if (flag) { puts("0"); return 0; } else flag = 1;
}
int pos = 0;
for (int i=1;i<=n;i++) {
if (a[i] != a[n-i+1]) { pos = i; break; }
t[ a[i] ] -= 2;
}
if (!pos) {
cout << 1LL * n * (n+1) / 2LL << endl;
return 0;
}
for (int i=pos;i<=n;i++) {
cur[ a[i] ]++;
if (2 * cur[ a[i] ] > t[ a[i] ]) {
if (i < n-i+1) break;
if (i == n-i+1 && t[ a[i] ] % 2 == 0) break;
if (a[i] != a[n-i+1]) break;
}
ret++;
}
memset(cur,0,sizeof(cur));
for (int i=n-pos+1;i>=1;i--) {
cur[ a[i] ]++;
if (cur[ a[i] ] * 2 > t[ a[i] ]) {
if (i > n-i+1) break;
if (i == n-i+1 && t[ a[i] ] % 2 == 0) break;
if (a[i] != a[n-i+1]) break;
}
ret++;
}
cout << 1LL * (pos) * (pos + ret) << endl;
return 0;
}