题目 | (∀x∀)
AtCoder Beginner Contest 242
E - (∀x∀)
https://atcoder.jp/contests/abc242/tasks/abc242_e
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : $500$ points
Problem Statement
Solve the following problem for $T$ test cases.
Given an integer $N$ and a string $S$, find the number of strings $X$ that satisfy all of the conditions below, modulo $998244353$.
- $X$ is a string of length $N$ consisting of uppercase English letters.
- $X$ is a palindrome.
$X \le S$ in lexicographical order.
- That is, $X=S$ or $X$ is lexicographically smaller than $S$.
Constraints
- $1 \le T \le 250000$
- $N$ is an integer between $1$ and $10^6$ (inclusive).
- In a single input, the sum of $N$ over the test cases is at most $10^6$.
- $S$ is a string of length $N$ consisting of uppercase English letters.
Input
Input is given from Standard Input in the following format:
$T$
$\mathrm{case}_1$
$\mathrm{case}_2$
$\vdots$
$\mathrm{case}_T$
Here, $\mathrm{case}_i$ represents the $i$-th test case.
Each test case is in the following format:
$N$
$S$
Output
Print $T$ lines. The $i$-th line should contain the answer for the $i$-th test case as an integer.
Sample Input 1
5
3
AXA
6
ABCZAZ
30
QWERTYUIOPASDFGHJKLZXCVBNMQWER
28
JVIISNEOXHSNEAAENSHXOENSIIVJ
31
KVOHEEMSOZZASHENDIGOJRTJVMVSDWW
Sample Output 1
24
29
212370247
36523399
231364016
This input contains five test cases.
Test case #1:
The $24$ strings satisfying the conditions are AAA
$,$ ABA
$,$ ACA
$,...,$ AXA
.
Test case #2:
$S$ may not be a palindrome.
Test case #3:
Be sure to find the count modulo $998244353$.
我的笔记
若回文串 $X$ 前半截的字典序就已经比 $S$ 小了,那么可以直接得出结论 $X<S$。
- 如:$X=ABCBA$ 和 $S=AZZZZ$,回文串前半截 $ABC$ 已经比 $AZZ$ 小了,因此 $X<S$。
若回文串 $X$ 前半截等于 $S$ 的前半截,那么需要比对后半截才能知道字典序的情况。
- 如:$X=ABCBA$ 和 $S=ABCAA$,不比对这俩的后半截是没法知道字典序情况的。
若回文串 $X$ 前半截的字典序就已经比 $S$ 大了,那么可以直接得出结论 $X>S$,即不符合该题要求。
- 如:$X=ABCBA$ 和 $S=AAAAA$,回文串前半截 $ABC$ 已经比 $AAA$ 大了,因此 $X>S$。
依靠上面第一条性质,可以先求出 $X$ 的前半截(就干脆写成 $X/2$ 吧)就已经比 $S/2$ 小的情况。
例如字符串 $S=BCADBABDDC$,先只考虑前半截 $S/2=BCADB$。我们要计算有多少种 $X/2$ 比 $S/2$ 小的情况:
$BCAD?$:第五位可选 $A$,共 $1\times26^0$ 种。
$BCA??$:第四位可选 $A,B,C$,第五位可选 $A\sim Z$,共 $3\times26^1$ 种。
$BC???$:第三位没法选,第四位可选 $A\sim Z$,第五位可选 $A\sim Z$,共 $0\times26^2$ 种
$B????$:第二位可选 $A,B$,第三位可选 $A\sim Z$,第四位可选 $A\sim Z$,第五位可选 $A\sim Z$,共 $2\times26^3$ 种。
$?????$:第一位可选 $A$,第二位可选 $A\sim Z$,第三位可选 $A\sim Z$,第四位可选 $A\sim Z$,第五位可选 $A\sim Z$,共 $1\times26^4$ 种。
将这些情况数目加起来,便是 $X/2<S/2$ 的情况。
那么还有一种情况有可能成立,不能忽略。就是上面第二条性质,回文串 $X$ 前半截等于 $S$ 的前半截的情况。这种情况只有一种,因此直接比较即可。算出 $X=BCADBBDACB$ 和 $S=BCADBABDDC$ 比较,$X>S$ 不满足题目要求。如果满足题目要求,答案 $+1$即可。
代码
#include <bits/stdc++.h>
#define MOD 998244353
using namespace std;
int main(void)
{
int T;
cin >> T;
while (T--)
{
int N;
string S;
cin >> N >> S;
long long ans = 0, p = 1;
for (int i = (N - 1) / 2; i >= 0; i--)
{
ans += p * (S[i] - 'A');
ans %= MOD;
p *= 26;
p %= MOD;
}
string palindrome = S;
for (int i = 0, j = N - 1; i <= j; i++, j--)
palindrome[j] = palindrome[i];
if (palindrome <= S)
{
ans++;
ans %= MOD;
}
cout << ans << endl;
}
return 0;
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi