結果
問題 | No.2724 Coprime Game 1 |
ユーザー | 🦠みどりむし |
提出日時 | 2024-04-12 23:21:49 |
言語 | C++23 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 7,226 bytes |
コンパイル時間 | 3,278 ms |
コンパイル使用メモリ | 259,576 KB |
実行使用メモリ | 21,392 KB |
最終ジャッジ日時 | 2024-10-02 23:49:43 |
合計ジャッジ時間 | 6,629 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 29 ms
21,260 KB |
testcase_01 | AC | 28 ms
15,880 KB |
testcase_02 | WA | - |
testcase_03 | TLE | - |
testcase_04 | -- | - |
testcase_05 | -- | - |
testcase_06 | -- | - |
testcase_07 | -- | - |
ソースコード
/* * @uni_kakurenbo * https://github.com/uni-kakurenbo/competitive-programming-workspace * * CC0 1.0 http://creativecommons.org/publicdomain/zero/1.0/deed.ja */ /* #language C++ 20 GCC */ #include <bits/stdc++.h> /* [begin]: snippet/aliases.hpp */ #include <cstdint> #include <utility> #include <vector> #include <ranges> /* [begin]: internal/dev_env.hpp */ #ifdef LOCAL_JUDGE inline constexpr bool DEV_ENV = true; inline constexpr bool NO_EXCEPT = false; #else inline constexpr bool DEV_ENV = false; inline constexpr bool NO_EXCEPT = true; #endif #if __cplusplus >= 202100L #define CPP20 true #define CPP23 true #elif __cplusplus >= 202002L #define CPP20 true #define CPP23 false #else #define CPP20 false #define CPP23 false #endif /* [end]: internal/dev_env.hpp*/ /* [begin]: snippet/internal/types.hpp */ namespace lib { using i16 = std::int16_t; using u16 = std::uint16_t; using i32 = std::int32_t; using u32 = std::uint32_t; using i64 = std::int64_t; using u64 = std::uint64_t; #ifdef __GNUC__ using i128 = __int128_t; using u128 = __uint128_t; #endif using uint = unsigned; using ll = long long; using ull = unsigned long long; using ld = long double; } /* [end]: snippet/internal/types.hpp*/ #define until(...) while(!(__VA_ARGS__)) #define CONTINUE(...) { __VA_ARGS__; continue; } #define BREAK(...) { __VA_ARGS__; break; } #define ALL(x) std::ranges::begin((x)),std::ranges::end((x)) #define RALL(x) std::ranges::rbegin((x)),std::ranges::rend((x)) #define $F first #define $S second namespace lib { constexpr char LN = '\n'; constexpr char SPC = ' '; constexpr std::pair<int,int> DIRS4[] = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } }; constexpr std::pair<int,int> DIRS4P[] = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 }, { 0, 0 } }; constexpr std::pair<int,int> DIRS8[] = { { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 } }; constexpr std::pair<int,int> DIRS8P[] = { { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 }, { 0, 0 } }; template<class T> using spair = std::pair<T,T>; } namespace std { using bit_reference = std::vector<bool>::reference; bit_reference operator |= (bit_reference a, const bool b) noexcept(NO_EXCEPT) { return a = a | b; } bit_reference operator &= (bit_reference a, const bool b) noexcept(NO_EXCEPT) { return a = a & b; } } /* [end]: snippet/aliases.hpp*/ void solve(); int prime[5000000]; std::vector<int> primes; signed main() { for(int i=2;i<=3000000;i++)prime[i]=1; for(int p=2;p*p<=3000000;p++)if(prime[p])for(int i=p*p;i<=3000000;i+=p)prime[i]=0; for(int i=2; i<=3000000; ++i) { if(prime[i]) primes.push_back(i); } int $ = 1; std::cin >> $; for(int _ = 0; _ < $; ++_) { solve(); } return 0; } using namespace std; #line 2 "multiplicative-function/prime-counting-o2d3.hpp" #line 2 "prime/prime-enumerate.hpp" // Prime Sieve {2, 3, 5, 7, 11, 13, 17, ...} vector<int> prime_enumerate(int N) { vector<bool> sieve(N / 3 + 1, 1); for (int p = 5, d = 4, i = 1, sqn = sqrt(N); p <= sqn; p += d = 6 - d, i++) { if (!sieve[i]) continue; for (int q = p * p / 3, r = d * p / 3 + (d * p % 3 == 2), s = 2 * p, qe = sieve.size(); q < qe; q += r = s - r) sieve[q] = 0; } vector<int> ret{2, 3}; for (int p = 5, d = 4, i = 1; p <= N; p += d = 6 - d, i++) if (sieve[i]) ret.push_back(p); while (!ret.empty() && ret.back() > N) ret.pop_back(); return ret; } #line 6 "multiplicative-function/prime-counting-o2d3.hpp" inline int64_t my_div(int64_t n, int64_t p) { return double(n) / p; }; int64_t prime_counting(long long N) { if(N < 2) return 0; using i64 = long long; i64 N6, N3, N2, N23, nsz; vector<i64> ns, h; vector<int> bit; // calculate N^{1/2}, N^{1/3}, N{1/6}, N{2/3} N2 = sqrt(N); N3 = pow(N, 1.0 / 3.0); while (N3 * N3 * N3 > N) N3--; while ((N3 + 1) * (N3 + 1) * (N3 + 1) <= N) N3++; N6 = sqrt(N3); N23 = N / N3; // precalc prime sieve below N ^ {1/2} auto prime = prime_enumerate(N2 + 1000); // index of prime int pidx = 0; // restore pi(p - 1) i64 pi = 0; // initialize ns ns.reserve(N2 * 2 + 2); ns.push_back(0); for (int i = 1; i <= N2; i++) ns.push_back(my_div(N, i)); for (int i = ns.back() - 1; i > 0; i--) ns.push_back(i); nsz = ns.size(); // initialize h copy(begin(ns), end(ns), back_inserter(h)); for (auto &i : h) --i; // p <= N ^ {1/6} while (prime[pidx] <= N6) { int p = prime[pidx]; i64 p2 = i64(p) * p; for (i64 i = 1, n = ns[i]; i < nsz && n >= p2; n = ns[++i]) h[i] -= h[i * p <= N2 ? i * p : nsz - my_div(n, p)] - pi; ++pidx; ++pi; } // fenwick tree, which restore [ h(p, 1), h(p, N ^ {2/3}) ) // bit[i] corresponds to h[i + N3] (1 <= i) bit.resize(nsz - N3); auto dfs = [&](auto rec, i64 cur, int pid, int flag) -> void { if (flag) { // if cur > N^{1/2} : // cur <= floor(N / id) // -> cur * id + n = N, n < id < cur // -> id <= floor(N / cur) int id = cur <= N2 ? nsz - cur : my_div(N, cur); // decrease h[N3] ~ h[id] if (id > N3) for (id -= N3; id; id -= id & -id) --bit[id]; } for (int dst = pid; cur * prime[dst] < N23; dst++) rec(rec, cur * prime[dst], dst, true); }; // N ^ {1/6} < p <= N ^ {1/3} while (prime[pidx] <= N3) { int p = prime[pidx]; i64 p2 = i64(p) * p; // update N ^ {2/3} <= n <= N for (i64 i = 1; i <= N3; i++) { // ns[i] >= p2 > N^{1/3} if (p2 > ns[i]) break; // id of floor(N/ip) int id = i * p <= N2 ? i * p : nsz - my_div(ns[i], p); // current value of h[id] i64 sm = h[id]; // if floor(N/ip) < N^{2/3}, add sum of fenwick tree if (id > N3) for (id -= N3; id < (int)bit.size(); id += id & -id) sm += bit[id]; h[i] -= sm - pi; } // update N ^ {1/3} <= n < N ^ {2/3}, using dfs dfs(dfs, p, pidx, false); ++pidx; ++pi; } // reflect fenwick tree for (int i = (int)bit.size() - 1; i; i--) { int j = i + (i & -i); if (j < (int)bit.size()) bit[i] += bit[j]; } for (int i = 1; i < (int)bit.size(); i++) h[i + N3] += bit[i]; // N ^ {1/3} < p <= N ^ {1/2} while (prime[pidx] <= N2) { int p = prime[pidx]; i64 p2 = i64(p) * p; for (i64 i = 1, n = ns[i]; i < nsz && n >= p2; n = ns[++i]) h[i] -= h[i * p <= N2 ? i * p : nsz - my_div(n, p)] - pi; ++pidx; ++pi; } return h[1]; } /** * @brief 邏謨ー繧ォ繧ヲ繝ウ繝・ $\mathrm{O}(N^{\frac{2}{3}})$ ) * @docs docs/multiplicative-function/prime-counting-o2d3.md */ int64_t euler_phi(int64_t n) { int64_t ret = n; for(int64_t i = 2; i * i <= n; i++) { if(n % i == 0) { ret -= ret / i; while(n % i == 0) n /= i; } } if(n > 1) ret -= ret / n; return ret; } // #include "template/debug.hpp" void solve() { long n; std::cin >> n; if(n == 2) { std::cout << "P\n"; return; } long mp = 1; for(long x = 2; ; ++x) { if(prime[x] && n % x == 0) { mp = x; break; } } std::cout << ((n - (prime_counting(n) - prime_counting(n / mp))) % 2 ? "K" : "P") << "\n"; }