の場合、 が答えです。以降 の場合を考えます。
正整数 が長さ の文字列の中に含まれるループ文字の個数としてあり得ることと、 が の約数であることは同値です。
理由は、文字列の末尾のループ文字 個を除いたとき、 個のループ文字とある非負整数個のスペースがこの順に並べられた文字列が 個並べられた文字列として考えられるためです。
また 個のループ文字を含む回文の個数は、先頭 個のループ文字を決めれば、他の文字も決まるため 個となります。
よって、 が答えです。
の約数の個数は 個に抑えられ、累乗計算は繰り返し二乗法を用いて で計算可能なため、 で解くことができました。
xxxxxxxxxx
using namespace std;
using namespace atcoder;
using mint = modint998244353;
vector<int> divisors(int n) {
vector<int> res;
for (int i = 1; i * i <= n; i++) {
if (n % i == 0) {
res.push_back(i);
if (i * i != n) res.push_back(n / i);
}
}
return res;
}
int main() {
int n, m;
cin >> n >> m;
if (m == 1) {
cout << n % 998244353 << endl;
return 0;
}
mint ans = 0;
for (int div : divisors(m - 1)) {
ans += mint(n).pow((div + 2) / 2);
}
cout << ans.val() << endl;
return 0;
}
xxxxxxxxxx
import math
MOD = 998244353
def divisors(n):
divisors = []
for i in range(1, int(math.sqrt(n)) + 1):
if n % i == 0:
divisors.append(i)
if i != n // i:
divisors.append(n // i)
return divisors
N, M = map(int, input().split())
if M == 1:
print(N % MOD)
exit()
ans = 0
for div in divisors(M - 1):
ans += pow(N, (div + 2) // 2, MOD)
ans %= MOD
print(ans)