結果
問題 | No.1396 Giri |
ユーザー | sash2104 |
提出日時 | 2021-02-14 21:42:20 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 508 ms / 2,000 ms |
コード長 | 5,177 bytes |
コンパイル時間 | 1,910 ms |
コンパイル使用メモリ | 186,460 KB |
実行使用メモリ | 11,276 KB |
最終ジャッジ日時 | 2024-07-22 09:11:03 |
合計ジャッジ時間 | 6,824 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 12 ms
7,696 KB |
testcase_01 | AC | 12 ms
7,692 KB |
testcase_02 | AC | 483 ms
11,276 KB |
testcase_03 | AC | 12 ms
7,680 KB |
testcase_04 | AC | 11 ms
7,692 KB |
testcase_05 | AC | 490 ms
11,152 KB |
testcase_06 | AC | 12 ms
7,692 KB |
testcase_07 | AC | 12 ms
7,692 KB |
testcase_08 | AC | 12 ms
7,560 KB |
testcase_09 | AC | 11 ms
7,564 KB |
testcase_10 | AC | 12 ms
7,664 KB |
testcase_11 | AC | 12 ms
7,680 KB |
testcase_12 | AC | 12 ms
7,680 KB |
testcase_13 | AC | 12 ms
7,688 KB |
testcase_14 | AC | 12 ms
7,692 KB |
testcase_15 | AC | 12 ms
7,560 KB |
testcase_16 | AC | 13 ms
7,688 KB |
testcase_17 | AC | 16 ms
7,564 KB |
testcase_18 | AC | 44 ms
7,948 KB |
testcase_19 | AC | 251 ms
9,608 KB |
testcase_20 | AC | 343 ms
10,120 KB |
testcase_21 | AC | 458 ms
10,768 KB |
testcase_22 | AC | 496 ms
11,020 KB |
testcase_23 | AC | 489 ms
11,276 KB |
testcase_24 | AC | 491 ms
11,276 KB |
testcase_25 | AC | 508 ms
11,144 KB |
ソースコード
#include <bits/stdc++.h> #define ALL(x) std::begin(x), std::end(x) using namespace std; // @title mod int #include <iostream> using ll = long long; // @title 素数判定、素因数分解 #include <cassert> #include <iostream> #include <vector> #include <map> using ll = long long; class Prime { // n以下の素数を列挙する public: const int n; std::vector<bool> is_prime; std::vector<int> primes; Prime(int size) : n(size), is_prime(n+1, true) { is_prime[0] = false; is_prime[1] = false; for (int i = 2; i <= n; ++i) { if (!is_prime[i]) continue; primes.push_back(i); int tmp = 2*i; while (tmp <= n) { is_prime[tmp] = false; tmp += i; } } } bool check(int x) { return is_prime[x]; } }; struct PrimeFactorization { // n*n以下の数についての素因数分解 const int n; Prime p; PrimeFactorization(int n) : n(n), p(n) {} std::map<ll, int> calc(ll a) { std::map<ll, int> ret; ll tmp = a; for (int i: p.primes) { if (i > tmp) break; int count = 0; while (tmp % i == 0) { ++count; tmp /= i; } if (count > 0) ret[i] = count; } if (tmp > 1) ret[tmp] = 1; return ret; } }; struct FastPrimeFactorization { /** * @brief n以下の数について高速で、n*n以下の数で普通に素因数分解を行う * */ int n; std::vector<int> divides; // その数を割り切る最小の素因数 std::vector<int> primes; // n以下の素数 FastPrimeFactorization(int n) : n(n), divides(n+1) { assert(n <= 2000000); // エラトステネスの篩にかけ、最小の素因数をdividesに書き込んでいく for (int i = 2; i <= n; ++i) { if (divides[i] > 0) continue; primes.push_back(i); int j = i; while (j <= n) { if (divides[j] == 0) { divides[j] = i; } j += i; } } // for (int i = 0; i <= n; ++i) { // cout << i << " " << divides[i] << endl; // } } std::map<ll, int> calc(ll a) { std::map<ll, int> ret; // 高速に計算できない部分は愚直にやる ll tmp = a; for (int i: primes) { if (tmp <= n || i > tmp) break; int count = 0; while (tmp % i == 0) { ++count; tmp /= i; } if (count > 0) ret[i] = count; } if (tmp > n) { // nより大きい素数 ret[tmp] = 1; return ret; } while (tmp > 1) { int d = divides[tmp]; ++ret[d]; tmp /= d; } return ret; } }; #if 0 using namespace std; int main() { FastPrimeFactorization pf(1000000); // PrimeFactorization pf(1000000); std::map<ll, int> factors; ll a = (ll)2*2*5*7*7*41; factors = pf.calc(a); cout << "prime factors of " << a << " is ..." << endl; for (auto it : factors) { cout << it.first << " " << it.second << endl; } cout << endl; // 最大数付近での確認 a = (ll)999983*999983; factors = pf.calc(a); cout << "prime factors of " << a << " is ..." << endl; for (auto it : factors) { cout << it.first << " " << it.second << endl; } } #endif #ifdef MUTABLE int mod; #else template<int mod> #endif struct ModInt { int val; ModInt inv() const{ int tmp,a=val,b=mod,x=1,y=0; while(b)tmp=a/b,a-=tmp*b,std::swap(a,b),x-=tmp*y,std::swap(x,y); return ModInt(x); } ModInt():val(0){} ModInt(ll x){if((val=x%mod)<0)val+=mod;} ModInt pow(ll t){ModInt res=1,b=*this; while(t){if(t&1)res*=b;b*=b;t>>=1;}return res;} ModInt& operator+=(const ModInt& x){if((val+=x.val)>=mod)val-=mod;return *this;} ModInt& operator-=(const ModInt& x){if((val+=mod-x.val)>=mod)val-=mod; return *this;} ModInt& operator*=(const ModInt& x){val=(ll)val*x.val%mod; return *this;} ModInt& operator/=(const ModInt& x){return *this*=x.inv();} bool operator==(const ModInt& x) const{return val==x.val;} bool operator!=(const ModInt& x) const{return val!=x.val;} bool operator<(const ModInt& x) const{return val<x.val;} bool operator<=(const ModInt& x) const{return val<=x.val;} bool operator>(const ModInt& x) const{return val>x.val;} bool operator>=(const ModInt& x) const{return val>=x.val;} ModInt operator+(const ModInt& x) const{return ModInt(*this)+=x;} ModInt operator-(const ModInt& x) const{return ModInt(*this)-=x;} ModInt operator*(const ModInt& x) const{return ModInt(*this)*=x;} ModInt operator/(const ModInt& x) const{return ModInt(*this)/=x;} friend std::ostream& operator<<(std::ostream& os, const ModInt& mi) { os << mi.val; return os; } static int get_mod() { return mod; } }; #ifndef MUTABLE using modint = ModInt<998244353>; #endif int main() { FastPrimeFactorization pf(1000001); int n; cin >> n; std::map<int, int> all; modint ans = 1; ll m = 0; for (int i = 1; i <= n; ++i) { std::map<ll, int> factors = pf.calc(i); for (auto it: factors) { all[it.first] = max(all[it.first], it.second); m = max(m, it.first); } } for (auto it: all) { ans *= modint(it.first).pow(it.second); } ans /= m; cout << ans << endl; return 0; }