题意
给字符串,求满足符合下面条件的子串个数。
条件:
- 该字符串能被分割成2k个部分,
- 每个部分前后相同,即下公式 (参考回文判断依据
思路
对于每个满足该条件的子串,其中心点可以枚举,两个指针向外拓展即可
比如下面这种情况,我们就能得到两个满足条件的子串。
因为每个子串的中心点是不会变化的,中心点相同的子串一定会被枚举到的
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
const int P = 13331;
typedef unsigned long long ull;
typedef long long ll;
ull p[N] = {1};
void solve()
{
string s;
cin >> s;
s = "0" + s;
int n = s.length() - 1;
vector<ull> f(n + 1);
for (int i = 1; i <= n; i++)
{
f[i] = f[i - 1] * P + s[i];
}
auto get = [&](int l, int r)
{
return f[r] - f[l - 1] * p[r - l + 1];
};
ll res = 0;
for (int k = 1; k <= n; k++)
{
int i = k, i2 = k;
int j = k + 1, j2 = k + 1;
while (i >= 1 && j <= n)
{
if (get(i, i2) == get(j2, j))
{
res++;
i2 = i - 1;
j2 = j + 1;
}
j++, i--;
}
}
cout << res << "\n";
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
for (int i = 1; i < N; i++)
p[i] = p[i - 1] * P;
while (t--)
{
solve();
}
}