A - Palindrome
题意:给出一个字符串,找出其中有多少个子串满足one-half-palindromic 的定义
思路:其实就是找一个i, j 使得 以i为中轴的回文串长度和以j为中轴的回文串长度都大于j - i + 1
先Manacher 预处理出以每个字符为中轴的最长回文串长度,然后用树状数组维护j ,枚举i
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long ll; 6 const int maxn = 5e5 + 10; 7 8 int l; 9 char Ma[maxn << 1]; 10 int Mp[maxn << 1]; 11 12 inline void Manacher(char s[], int len) 13 { 14 l = 0; 15 Ma[l++] = '$'; 16 Ma[l++] = '#'; 17 for(int i = 0; i < len; ++i) 18 { 19 Ma[l++] = s[i]; 20 Ma[l++] = '#'; 21 } 22 Ma[l] = 0; 23 int mx = 0, id = 0; 24 for(int i = 0; i < l; ++i) 25 { 26 Mp[i] = mx > i ? min(Mp[2 * id - i], mx - i) : 1; 27 while(Ma[i + Mp[i]] == Ma[i - Mp[i]]) Mp[i]++; 28 if(i + Mp[i] > mx) 29 { 30 mx = i + Mp[i]; 31 id = i; 32 } 33 } 34 } 35 36 int cnt[maxn << 1]; 37 char str[maxn]; 38 int a[maxn]; 39 int len; 40 41 vector <int> vv[maxn]; 42 43 inline int lowbit(int x) 44 { 45 return x & (-x); 46 } 47 48 inline void update(int x, int val) 49 { 50 for (int i = x; i <= len; i += lowbit(i)) 51 a[i] += val; 52 } 53 54 inline int query(int x) 55 { 56 int res = 0; 57 for (int i = x; i > 0; i -= lowbit(i)) 58 res += a[i]; 59 return res; 60 } 61 62 int main() 63 { 64 int t; 65 scanf("%d", &t); 66 while(t--) 67 { 68 memset(a, 0, sizeof a); 69 scanf("%s", str); 70 len = strlen(str); 71 Manacher(str, len); 72 ll ans = 0; 73 int pos = 1; 74 for(int i = 2 ; i < l; i += 2) 75 { 76 cnt[pos]= Mp[i] / 2 - 1; 77 vv[pos - cnt[pos]].push_back(pos); 78 pos++; 79 } 80 for(int i = 1; i <= pos; ++i) 81 { 82 for (auto it : vv[i]) 83 { 84 update(it, 1); 85 } 86 vv[i].clear(); 87 ans += query(i + cnt[i]) - query(i); 88 // cout << ans << endl; 89 } 90 printf("%lld\n",ans); 91 } 92 return 0; 93 }