結果

問題 No.2318 Phys Bone Maker
ユーザー CoCo_Japan_panCoCo_Japan_pan
提出日時 2023-05-27 14:40:16
言語 C++17(gcc12)
(gcc 12.3.0 + boost 1.87.0)
結果
AC  
実行時間 1,153 ms / 3,000 ms
コード長 10,293 bytes
コンパイル時間 12,837 ms
コンパイル使用メモリ 298,724 KB
最終ジャッジ日時 2025-02-13 09:16:56
ジャッジサーバーID
(参考情報)
judge1 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 45
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

#line 2 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/template/procon.hpp"
#ifndef DEBUG
// assert
#ifndef NDEBUG
#define NDEBUG
#endif
//
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#endif
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define ALL(x) (x).begin(), (x).end()
template <class T>
using vec = vector<T>;
template <class T, class S>
inline bool chmax(T &a, const S &b) {
return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
return (a > b ? a = b, 1 : 0);
}
template <class T>
constexpr T INF = 1'000'000'000;
template <>
constexpr int INF<int> = 1'000'000'000;
template <>
constexpr ll INF<ll> = ll(INF<int>) * INF<int> * 2;
#line 2 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/modint/modint_static.hpp"
#line 2 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/modint/innermath_modint.hpp"
#line 4 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/modint/innermath_modint.hpp"
namespace innermath_modint{
using ll = long long;
using ull = unsigned long long;
// xmod[0, mod)
constexpr ll safe_mod(ll x, ll mod) {
x %= mod;
if (x < 0) x += mod;
return x;
}
constexpr ll pow_mod_constexpr(ll x, ll n, ll mod) {
if (mod == 1) return 0;
ll ret = 1;
ll beki = safe_mod(x, mod);
while (n) {
// LSB
if (n & 1) {
ret = (ret * beki) % mod;
}
beki = (beki * beki) % mod;
n >>= 1;
}
return ret;
}
// int(2^32)
constexpr bool is_prime_constexpr(int n) {
if (n <= 1) return false;
if (n == 2 || n == 7 || n == 61) return true;
if (n % 2 == 0) return false;
// inta={2,7,61}
constexpr ll bases[] = {2, 7, 61};
// n-1 = 2^r * d
ll d = n - 1;
while (d % 2 == 0) d >>= 1;
// mod1
//
for (ll a : bases) {
ll t = d;
ll y = pow_mod_constexpr(a, t, n);
// y1n-1
while (t != n - 1 && y != 1 && y != n - 1) {
y = (y * y) % n;
t <<= 1;
}
// 11-1()
if (y != n - 1 && t % 2 == 0) {
return false;
}
}
return true;
}
// g = gcd(a,b)ax = g (mod b)0 <= x <
// b/g
constexpr std::pair<ll, ll> inv_gcd(ll a, ll b) {
a = safe_mod(a, b);
// ab
if (a == 0) return {b, 0};
// 0 <= a < b
// [1] s - m0 * a = 0 (mod b)
// [2] t - m1 * a = 0 (mod b)
// [3] s * |m1| + t * |m0| <= b
ll s = b, t = a;
ll m0 = 0, m1 = 1;
while (t) {
// s → s mod t
// m0 → m0 - m1 * (s / t)
ll u = s / t;
s -= t * u;
m0 -= m1 * u;
{
ll tmp = t;
t = s;
s = tmp;
}
{
ll tmp = m1;
m1 = m0;
m0 = tmp;
}
}
// s = gcd(a, b)
//
// [1] k * s - m0 * a = 0 (mod b)
// [2] s - m1 * a = 0 (mod b)
// [3] (k * s) * |m1| + s * |m0| <= b
// |m0| < b / s
if (m0 < 0) m0 += b / s;
return {s, m0};
}
}
#line 5 "/home/cocojapanpan/Procon_CPP/proconLibrary/lib/modint/modint_static.hpp"
template <const int MOD>
struct modint_static {
using ll = long long;
public:
constexpr modint_static(ll x = 0) noexcept : value(x % MOD) {
if (value < 0) value += MOD;
}
constexpr int get_mod() const noexcept { return MOD; }
constexpr ll val() const noexcept { return value; }
constexpr modint_static operator-() const noexcept {
return modint_static(-value);
}
constexpr modint_static& operator++() noexcept {
++value;
if(value == MOD) value = 0;
return *this;
}
constexpr modint_static& operator--() noexcept {
if(value == 0) value = MOD;
--value;
return *this;
}
constexpr modint_static operator++(int) noexcept {
modint_static cpy(*this);
++(*this);
return cpy;
}
constexpr modint_static operator--(int) noexcept {
modint_static cpy(*this);
--(*this);
return cpy;
}
constexpr modint_static& operator+=(const modint_static& rhs) noexcept {
value += rhs.value;
if (value >= MOD) value -= MOD;
return *this;
}
constexpr modint_static& operator-=(const modint_static& rhs) noexcept {
value += (MOD - rhs.value);
if (value >= MOD) value -= MOD;
return *this;
}
constexpr modint_static& operator*=(const modint_static& rhs) noexcept {
(value *= rhs.value) %= MOD; //
return *this;
}
constexpr modint_static operator+(const modint_static& rhs) const noexcept {
modint_static cpy(*this);
return cpy += rhs;
}
constexpr modint_static operator-(const modint_static& rhs) const noexcept {
modint_static cpy(*this);
return cpy -= rhs;
}
constexpr modint_static operator*(const modint_static& rhs) const noexcept {
modint_static cpy(*this);
return cpy *= rhs;
}
constexpr modint_static pow(ll beki) const noexcept {
modint_static curbekimod(*this);
modint_static ret(1);
while (beki > 0) {
if (beki & 1) ret *= curbekimod;
curbekimod *= curbekimod;
beki >>= 1;
}
return ret;
}
// value
constexpr modint_static inv() const noexcept {
//
auto [gcd_value_mod, inv_value] = innermath_modint::inv_gcd(value, MOD);
assert(gcd_value_mod == 1);
return modint_static(inv_value);
}
constexpr modint_static& operator/=(const modint_static& rhs) noexcept {
return (*this) *= rhs.inv();
}
constexpr modint_static operator/(const modint_static& rhs) const noexcept {
modint_static cpy(*this);
return cpy /= rhs;
}
private:
ll value;
};
using mint998244353 = modint_static<998244353>;
using mint1000000007 = modint_static<1000000007>;
#line 3 "main.cpp"
using mint = mint998244353;
ll N;
vec<int> primeList;
map<ll, int> primeFactorized;
vec<pair<ll, map<ll, int>>> divisorsWithFactor{{1, {}}};
map<ll, int> divisorsToIndex;
vec<mint> dp;
void primeEnumerate() {
int size = sqrt(N);
vec<bool> seen(size + 1, false);
for(int i = 2; i <= size; i++) {
if(seen[i]) continue;
primeList.push_back(i);
for(int j = i; j <= size; j += i) {
seen[j] = true;
}
}
}
void primeFactorizeN() {
ll curN = N;
for(ll prime : primeList) {
while(curN % prime == 0) {
curN /= prime;
++primeFactorized[prime];
}
}
if(curN != 1) {
++primeFactorized[curN];
}
}
void divisorsFactorize(map<ll, int>::iterator curIt) {
if(curIt == primeFactorized.end()) return;
int size = divisorsWithFactor.size();
ll prime = curIt -> first;
int beki = curIt -> second;
for(int i = 0; i < size; i++) {
ll cur = 1;
for(int j = 1; j <= beki; j++) {
cur *= prime;
ll newNum = divisorsWithFactor[i].first * cur;
map<ll, int> newMap = divisorsWithFactor[i].second;
newMap[prime] = j;
divisorsWithFactor.emplace_back(newNum, newMap);
}
}
divisorsFactorize(next(curIt));
}
// debug
void printDivisorsFactorized() {
for(const pair<ll, map<ll, int>> &p : divisorsWithFactor) {
cerr << p.first << "\n";
for(pair<ll, int> mp : p.second) {
cerr << ":" << mp.first << " :" << mp.second << "\n";
}
}
cerr << endl;
}
void enumerateDivisors(const map<ll, int> &mp, vec<ll> &ret) {
ret.clear();
ret.push_back(1);
for(const pair<ll, int> &p : mp) {
int size = ret.size();
ll prime = p.first;
for(int i = 0; i < size; i++) {
ll cur = 1;
for(int j = 1; j <= p.second; j++) {
cur *= prime;
ret.push_back(ret[i] * cur);
}
}
}
}
// debug
void printDivisors() {
vec<ll> divisors;
enumerateDivisors(divisorsWithFactor.back().second, divisors);
for(ll d: divisors) {
cerr << d << " ";
}
cerr << endl;
}
void compDP() {
int size = divisorsWithFactor.size();
dp.assign(size, 0);
dp[0] = 1;
for(int i = 1; i < size; i++) {
vec<ll> divisors;
enumerateDivisors(divisorsWithFactor[i].second, divisors);
for(ll d : divisors) {
if(d == divisorsWithFactor[i].first) break;
ll q = divisorsWithFactor[i].first / d;
// dq
mint ziyudo = 1;
for(pair<ll, int> p : divisorsWithFactor[divisorsToIndex[d]].second) {
if(divisorsWithFactor[divisorsToIndex[q]].second.count(p.first)) continue;
ziyudo *= (p.second + 1);
}
dp[i] += dp[divisorsToIndex[d]] * ziyudo;
}
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> N;
primeEnumerate();
primeFactorizeN();
divisorsFactorize(primeFactorized.begin());
// printDivisors();
for(int i = 0; i < (int)divisorsWithFactor.size(); i++) {
divisorsToIndex[divisorsWithFactor[i].first] = i;
}
compDP();
cout << dp.back().val() << "\n";
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0