arc155A
题目传送门:
题意:
给你一个长度为 n n n 的字符串 s s s,问你是否存在一个长度为 k k k 的字符串 s ′ s' s′ 使得 s + s ′ s + s' s+s′ 和 s ′ + s s' + s s′+s 都是回文串。
solution:
我们分讨一下。
-
k < n k < n k<n
对于这种情况我们发现只需 s s s 的后 n − k n - k n−k 个字符与前 n − k n - k n−k 个字符都是回文串且前 k k k 个字符与后 k k k 个字符相等即可。
-
⌊ k n ⌋ m o d 2 = 0 \left \lfloor \dfrac{k}{n} \right\rfloor \bmod 2 = 0 ⌊nk⌋mod2=0
我们只需要在两端各加上一些正着或倒着的 s s s,那最后就变成了 k k k 为 k m o d n k \bmod n kmodn 时的情况 1 1 1 了。
-
⌊ k n ⌋ m o d 2 = 1 \left \lfloor \dfrac{k}{n} \right\rfloor \bmod 2 = 1 ⌊nk⌋mod2=1
同样我们在一端各加上一个倒着的 s s s,就变成了 s s s 为 s + 倒着的 s s + \text{倒着的}s s+倒着的s, k k k 为 k − n k - n k−n 时的情况 2 2 2 了。
code: 时间复杂度 O ( n ) \mathcal{O}(n) O(n)
#include <bits/stdc++.h>
#define int ll
#define endl '\n'
#define il inline
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
string s;
int n, k;
il bool hw(string s) // 判回文
{
for (int i = 0; i < s.size(); i++)
if (s[i] != s[s.size() - i - 1])
return 0;
return 1;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--)
{
cin >> n >> k >> s;
if ((k / n) & 1) // 情况三
{
k -= n;
string t;
for (int i = 0; i < s.size(); i++)
t += s[s.size() - i - 1];
s = t + s, n *= 2;
}
k %= n; // 情况二
if (s.substr(0, k) == s.substr(n - k, k)) // 情况一
cout << (hw(s.substr(k, n - k)) && hw(s.substr(0, n - k)) ? "Yes" : "No") << endl;
else
cout << "No" << endl;
}
return 0;
}