結果
問題 | No.28 末尾最適化 |
ユーザー | furon |
提出日時 | 2023-06-01 20:50:01 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 335 ms / 5,000 ms |
コード長 | 2,139 bytes |
コンパイル時間 | 1,666 ms |
コンパイル使用メモリ | 133,708 KB |
実行使用メモリ | 5,248 KB |
最終ジャッジ日時 | 2024-12-28 15:14:42 |
合計ジャッジ時間 | 2,440 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 335 ms
5,248 KB |
ソースコード
#include <iostream> #include <iomanip> #include <vector> #include <algorithm> #include <functional> #include <cmath> #include <string> #include <queue> #include <map> #include <bitset> #include <set> #include <stack> #include <numeric> #include <unordered_map> #include <random> using namespace std; using ll = long long; using vi = vector<int>; using vvi = vector<vi>; using vl = vector<ll>; using vvl = vector<vl>; using vb = vector<bool>; using vvb = vector<vb>; using vd = vector<double>; using vs = vector<string>; using pii = pair<int, int>; using pll = pair<ll, ll>; using pdd = pair<double, double>; using vpii = vector<pii>; using vpll = vector<pll>; using vpdd = vector<pdd>; const int inf = (1 << 30) - 1; const ll INF = 1LL << 60; //const int MOD = 1000000007; const int MOD = 998244353; vector<pii> prime_factorize(ll N) { vector<pii> res; for (ll a = 2; a * a <= N; ++a) { if (N % a != 0) continue; ll ex = 0; while (N % a == 0) { ++ex; N /= a; } res.push_back({ a, ex }); } if (N != 1) res.push_back({ N, 1 }); return res; } template<class T1, class T2> ostream& operator <<(ostream& s, pair<T1, T2> P) { return s << P.first << " " << P.second; } int main() { int q; cin >> q; int mod = 100000009; while (q--) { int seed, n, k, b; cin >> seed >> n >> k >> b; vl x(n + 1); x[0] = seed; for (int i = 0; i < n; i++) { x[i + 1] = 1 + (x[i] * x[i] + 12345 * x[i]) % mod; } // Bの素因数が一組揃うとB進数で0になる // 例として、B=12(2^2*3^1)の時、Tの素因数について // min(2の数/2, 3の数) が答えになるので、 // それぞれの素因数について、Xの小さい方からK個分 // 選んだ時の最小値を探す vpii pb = prime_factorize(b); int ans = inf; for (auto [p, num] : pb) { vi cnt(n + 1, 0); for (int i = 0; i <= n; i++) { int tmp = x[i]; while (x[i] % p == 0) { x[i] /= p; cnt[i]++; } } sort(cnt.begin(), cnt.end()); int sum = 0; for (int i = 0; i < k; i++) { sum += cnt[i]; } ans = min(ans, (int)(sum / num)); } cout << ans << endl; } return 0; }