結果
問題 | No.68 よくある棒を切る問題 (2) |
ユーザー | codershifth |
提出日時 | 2015-07-29 20:32:15 |
言語 | C++11 (gcc 13.3.0) |
結果 |
AC
|
実行時間 | 1,117 ms / 5,000 ms |
コード長 | 2,827 bytes |
コンパイル時間 | 1,918 ms |
コンパイル使用メモリ | 169,332 KB |
実行使用メモリ | 46,236 KB |
最終ジャッジ日時 | 2024-07-17 22:21:05 |
合計ジャッジ時間 | 19,331 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1,081 ms
46,108 KB |
testcase_01 | AC | 1,108 ms
46,112 KB |
testcase_02 | AC | 1,117 ms
46,236 KB |
testcase_03 | AC | 1,070 ms
46,108 KB |
testcase_04 | AC | 1,063 ms
46,112 KB |
testcase_05 | AC | 1,060 ms
46,236 KB |
testcase_06 | AC | 1,064 ms
45,932 KB |
testcase_07 | AC | 1,063 ms
45,960 KB |
testcase_08 | AC | 1,004 ms
45,776 KB |
testcase_09 | AC | 1,020 ms
45,852 KB |
ソースコード
#include <bits/stdc++.h> typedef long long ll; typedef unsigned long long ull; #define FOR(i,a,b) for(int (i)=(a);i<(b);i++) #define REP(i,n) FOR(i,0,n) #define RANGE(vec) (vec).begin(),(vec).end() using namespace std; class CuttingStick2 { public: void solve(void) { // // クエリ数が多いので二分探索では O(N*Q*log(N)) では間に合わない // そこで以下のように考える // // 各 L から a[i] 本切り出すとする // L[0] L[1] ... L[N-1] // a[0] a[1] ... a[N-1] // // ∑ a[i] = K なる {a[i]} (K の分割数) と考えると // i // // D(K) = min{L[i]/a[i]} が K のこの分割 a(K) での最大長となる。 // i // // ある K にたいして D(K) を最大にする分割 A がもとまっているとき // D(K+1) を最大にする分割 A' は // // L[j]/(A[j]+1) が最大になる j を使って // // A' = {A[0],...,A[j]+1,...,A[N-1]} と表せる。 // (つまり K+1 の最適な分割は K の最適分割から導かれる) // // なぜなら 別の最適な K+1 の分割 B があるとすると L[ii]/B[ii] < min(L[i]/A[i], L[j]/(A[j]+1)) // となるので B から A よりも最適な K の分割がつくれてしまう。(不要な棒をすてればよい) // // よってこの逐次更新結果を保持しておけば各クエリに O(1) で答えられる。 // O(maxK*log(N)) int N; cin>>N; vector<double> L(N); REP(i,N) cin>>L[i]; int maxK = (int)5*10E+5; vector<double> ans(maxK+1,0); vector<ll> a(N,0); priority_queue<pair<double,int>> que; REP(i,N) que.emplace(L[i],i); double D = 1E+9; for (int k = 1; k <= maxK; ++k) { double l; int i; tie(l,i) = que.top(); // L[i]/(a[i]+1) が最大になる i を取得 que.pop(); D = min(D, l); ++a[i]; ans[k] = D; que.emplace(L[i]/(a[i]+1),i); } int Q; cin>>Q; REP(i,Q) { int K; cin>>K; cout<<setprecision(20)<<ans[K]<<endl; } } }; #if 1 int main(int argc, char *argv[]) { ios::sync_with_stdio(false); auto obj = new CuttingStick2(); obj->solve(); delete obj; return 0; } #endif