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 }
View Code

相关文章: