結果
問題 | No.1728 [Cherry 3rd Tune] Bullet |
ユーザー | hitonanode |
提出日時 | 2021-10-29 22:28:58 |
言語 | C++23 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 24 ms / 2,000 ms |
コード長 | 3,024 bytes |
コンパイル時間 | 1,634 ms |
コンパイル使用メモリ | 122,532 KB |
実行使用メモリ | 7,968 KB |
最終ジャッジ日時 | 2024-10-07 12:05:03 |
合計ジャッジ時間 | 3,074 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 10 ms
7,756 KB |
testcase_01 | AC | 11 ms
7,884 KB |
testcase_02 | AC | 11 ms
7,888 KB |
testcase_03 | AC | 11 ms
7,884 KB |
testcase_04 | AC | 11 ms
7,884 KB |
testcase_05 | AC | 11 ms
7,880 KB |
testcase_06 | AC | 11 ms
7,760 KB |
testcase_07 | AC | 11 ms
7,884 KB |
testcase_08 | AC | 13 ms
7,884 KB |
testcase_09 | AC | 15 ms
7,968 KB |
testcase_10 | AC | 15 ms
7,884 KB |
testcase_11 | AC | 13 ms
7,808 KB |
testcase_12 | AC | 14 ms
7,752 KB |
testcase_13 | AC | 15 ms
7,752 KB |
testcase_14 | AC | 13 ms
7,756 KB |
testcase_15 | AC | 16 ms
7,880 KB |
testcase_16 | AC | 13 ms
7,884 KB |
testcase_17 | AC | 14 ms
7,764 KB |
testcase_18 | AC | 14 ms
7,760 KB |
testcase_19 | AC | 15 ms
7,756 KB |
testcase_20 | AC | 13 ms
7,884 KB |
testcase_21 | AC | 15 ms
7,880 KB |
testcase_22 | AC | 14 ms
7,880 KB |
testcase_23 | AC | 24 ms
7,808 KB |
testcase_24 | AC | 22 ms
7,884 KB |
testcase_25 | AC | 17 ms
7,888 KB |
testcase_26 | AC | 11 ms
7,808 KB |
ソースコード
#include <algorithm> #include <cassert> #include <iostream> #include <map> #include <vector> using namespace std; // Linear sieve algorithm for fast prime factorization // Complexity: O(N) time, O(N) space: // - MAXN = 10^7: ~44 MB, 80~100 ms (Codeforces / AtCoder GCC, C++17) // - MAXN = 10^8: ~435 MB, 810~980 ms (Codeforces / AtCoder GCC, C++17) // Reference: // [1] D. Gries, J. Misra, "A Linear Sieve Algorithm for Finding Prime Numbers," // Communications of the ACM, 21(12), 999-1003, 1978. // - https://cp-algorithms.com/algebra/prime-sieve-linear.html // - https://37zigen.com/linear-sieve/ struct Sieve { std::vector<int> min_factor; std::vector<int> primes; Sieve(int MAXN) : min_factor(MAXN + 1) { for (int d = 2; d <= MAXN; d++) { if (!min_factor[d]) { min_factor[d] = d; primes.emplace_back(d); } for (const auto &p : primes) { if (p > min_factor[d] or d * p > MAXN) break; min_factor[d * p] = p; } } } // Prime factorization for 1 <= x <= MAXN^2 // Complexity: O(log x) (x <= MAXN) // O(MAXN / log MAXN) (MAXN < x <= MAXN^2) template <typename T> std::map<T, int> factorize(T x) const { std::map<T, int> ret; assert(x > 0 and x <= ((long long)min_factor.size() - 1) * ((long long)min_factor.size() - 1)); for (const auto &p : primes) { if (x < T(min_factor.size())) break; while (!(x % p)) x /= p, ret[p]++; } if (x >= T(min_factor.size())) ret[x]++, x = 1; while (x > 1) ret[min_factor[x]]++, x /= min_factor[x]; return ret; } // Enumerate divisors of 1 <= x <= MAXN^2 // Be careful of highly composite numbers https://oeis.org/A002182/list https://gist.github.com/dario2994/fb4713f252ca86c1254d#file-list-txt // (n, (# of div. of n)): 45360->100, 735134400(<1e9)->1344, 963761198400(<1e12)->6720 template <typename T> std::vector<T> divisors(T x) const { std::vector<T> ret{1}; for (const auto p : factorize(x)) { int n = ret.size(); for (int i = 0; i < n; i++) { for (T a = 1, d = 1; d <= p.second; d++) { a *= p.first; ret.push_back(ret[i] * a); } } } return ret; // NOT sorted } }; Sieve sieve((1 << 20)); #include <atcoder/modint> using mint = atcoder::modint1000000007; mint solve() { int N, C; cin >> N >> C; mint ret = mint(C).pow(N) * N; map<int, int> mp; for (auto d : sieve.divisors(N)) mp[d] = N / d; for (auto [p, deg] : sieve.factorize(N)) { for (auto [a, b] : mp) { if (a % p == 0) mp[a / p] -= mp[a]; } } for (auto [d, val] : mp) { ret += mint(C).pow(d * 2) * val; } return ret / (N * 2); } int main() { int T; cin >> T; while (T--) cout << solve().val() << '\n'; }