题目 | Make It Square
2023牛客暑期多校训练营8
I - Make It Square
https://ac.nowcoder.com/acm/contest/57362/I
题意
给定串 AA
型的串,其中 A
为一任意非空字符串。可用字符集为小写字母。对
题解
特殊情况
首先特判掉几个特殊情况,从而将问题拆分简化。
由于
那么可以直接判断:如果
为奇数
由于
的情况
这种情况的示意图如下,为了方便,令
由于要求整个字符串从中心分开后,两个子串一致。因此我们把上面这个字符串从中心切成两半,再对齐摆到一起,此时两个字符串的对应位置应该时相等的。
- 若
,那么这个图的样子如下(图中标注的均为长度):
上面两行代表的字符串必须对应位置相对,而
因此如果要满足题目条件,那么
如果
如果
对于如何判断是否符合上面的条件,第一条直接遍历判断就行,复杂度为
第二条的含义是字符串
- 若
,那么这个图的样子如下:
可以发现,此时
那么如果要满足题目条件,
如果
如果
的情况
这种情况的示意图如下:
这种情况实际上和上面的思考方式完全一致,实际上代码只需要改几个变量名就行了,因此下面只放出来示意图,不再解释。
代码
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
constexpr int MOD = 998244353;
class KMP
{
vector<int> nxt;
string pat;
public:
KMP(string &s)
{
pat = s;
int n = pat.length();
int j = 0;
nxt.resize(n);
for (int i = 1; i < n; i++)
{
while (j > 0 && pat[i] != pat[j])
j = nxt[j - 1];
if (pat[i] == pat[j])
j++;
nxt[i] = j;
}
}
vector<int> find(string &txt)
{
int n = pat.length(), m = txt.length();
int j = 0;
vector<int> ans;
for (int i = 0; i < m; i++)
{
while (j > 0 && txt[i] != pat[j])
j = nxt[j - 1];
if (txt[i] == pat[j])
j++;
if (j == n)
{
ans.push_back(i - n + 1);
j = nxt[j - 1];
}
}
return ans;
}
set<int> get_border()
{
set<int> s;
int cur = nxt.back();
while (cur)
{
s.insert(cur);
cur = nxt[cur - 1];
}
s.insert(0);
return s;
}
};
void solve()
{
int m;
cin >> m;
string s, t;
cin >> s >> t;
int ls = s.size(), lt = t.size();
if (ls == lt)
{
if (s != t)
{
for (int i = 1; i <= m; i++)
cout << 0 << " \n"[i == m];
}
else
{
int ans = 1;
for (int i = 1; i <= m; i++)
{
ans = ans * 26 % MOD;
cout << ans << " \n"[i == m];
}
}
return;
}
if ((ls + lt) % 2 == 1)
{
for (int i = 1; i <= m; i++)
cout << 0 << " \n"[i == m];
return;
}
if (ls > lt)
{
for (int i = lt - 1, j = ls - 1 - (ls - lt) / 2; i >= 0; i--, j--)
{
if (t[i] != s[j])
{
for (int i = 1; i <= m; i++)
cout << 0 << " \n"[i == m];
return;
}
}
int ans = 1;
KMP kmp_s(s);
auto border_s = kmp_s.get_border();
for (int i = 1; i <= m; i++)
{
if (i > (ls - lt) / 2)
{
ans = ans * 26 % MOD;
cout << ans << " \n"[i == m];
}
else
{
if (border_s.count((ls - lt) / 2 - i) == 0)
cout << 0 << " \n"[i == m];
else
cout << 1 << " \n"[i == m];
}
}
}
else // if (ls <= lt)
{
for (int i = ls - 1, j = lt - 1 - (lt - ls) / 2; i >= 0; i--, j--)
{
if (s[i] != t[j])
{
for (int i = 1; i <= m; i++)
cout << 0 << " \n"[i == m];
return;
}
}
int ans = 1;
KMP kmp_t(t);
auto border_t = kmp_t.get_border();
for (int i = 1; i <= m; i++)
{
if (i > (lt - ls) / 2)
{
ans = ans * 26 % MOD;
cout << ans << " \n"[i == m];
}
else
{
if (border_t.count((lt - ls) / 2 - i) == 0)
cout << 0 << " \n"[i == m];
else
cout << 1 << " \n"[i == m];
}
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
// cin >> t;
while (t--)
solve();
return 0;
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi