Submission #1288238

#TimeUsernameProblemLanguageResultExecution timeMemory
1288238tunademayoLet's Win the Election (JOI22_ho_t3)C++20
10 / 100
1 ms348 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; struct Fenwick { int n; vector<long double> bitSum; vector<int> bitCnt; Fenwick(int n=0){ init(n); } void init(int n_){ n = n_; bitSum.assign(n+1, 0.0L); bitCnt.assign(n+1, 0); } void add(int idx, long double val, int cnt){ for(int i = idx; i <= n; i += i & -i){ bitSum[i] += val; bitCnt[i] += cnt; } } // prefix sum, prefix count long double sumPrefix(int idx){ long double s = 0; for(int i = idx; i > 0; i -= i & -i) s += bitSum[i]; return s; } int cntPrefix(int idx){ int s = 0; for(int i = idx; i > 0; i -= i & -i) s += bitCnt[i]; return s; } // find smallest position p such that cntPrefix(p) >= k. assume k >= 1 and k <= total count int findByCount(int k){ int pos = 0; int LOG = 1; while((1<<LOG) <= n) ++LOG; for(int pw = 1<<LOG; pw; pw >>= 1){ if(pos + pw <= n && bitCnt[pos + pw] < k){ k -= bitCnt[pos + pw]; pos += pw; } } return pos + 1; } }; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int N, K; if(!(cin >> N >> K)) return 0; vector<long double> A(N); vector<long double> B(N); for(int i=0;i<N;++i){ ll ai, bi; cin >> ai >> bi; A[i] = (long double)ai; B[i] = (long double)bi; // bi == -1 means no collaborator } // collect collaborator candidates vector<pair<long double,int>> coll; // (Bi, idx) for(int i=0;i<N;++i) if(B[i] >= 0) coll.emplace_back(B[i], i); sort(coll.begin(), coll.end(), [](auto &p1, auto &p2){ if(p1.first != p2.first) return p1.first < p2.first; return p1.second < p2.second; }); // prepare Ai sorted list (value, idx) vector<pair<long double,int>> allA; allA.reserve(N); for(int i=0;i<N;++i) allA.emplace_back(A[i], i); sort(allA.begin(), allA.end()); // Fenwick over sorted by Ai positions: initially include all states Fenwick fw(N); // position map: idx -> position in sorted allA (1-based) vector<int> pos(N); for(int i=0;i<N;++i){ pos[allA[i].second] = i+1; } for(int i=0;i<N;++i){ fw.add(i+1, (long double)allA[i].first, 1); } long double ans = 1e100L; int maxColl = (int)coll.size(); int limit = min(K, maxColl); // We will iterate i = number of collaborators we will obtain (0..limit) // As we increase i, we remove that state's Ai from BIT (since it's already "used" and counted among votes) long double t0 = 0.0L; // prefix time to get i collaborators for(int i = 0; i <= limit; ++i){ int haveVotesFromColl = i; // each collaborator state gives vote (Bi >= Ai guaranteed) int need = K - haveVotesFromColl; if(need <= 0){ // already have >= K votes ans = min(ans, t0); } else { // check how many available states remain in BIT int available = fw.cntPrefix(N); if(available >= need){ // get sum of smallest 'need' Ai among available int posK = fw.findByCount(need); int cntBefore = fw.cntPrefix(posK-1); long double sumBefore = fw.sumPrefix(posK-1); int takeAtPos = need - cntBefore; long double valAtPos = allA[posK-1].first; long double sumNeed = sumBefore + valAtPos * (long double)takeAtPos; long double totalTime = t0 + sumNeed / (1.0L + (long double)i); if(totalTime < ans) ans = totalTime; } } // prepare for next i: if i == limit we stop; otherwise include next collaborator (remove its Ai from BIT and add time to t0) if(i == limit) break; // collaborator to be obtained is coll[i] (0-based) long double Bi = coll[i].first; int idx = coll[i].second; // time to get this collaborator when currently have (1 + i) speakers: we must spend Bi / (1 + i) additional time // BUT we must consider cumulative effect: previously t0 already sum for earlier collaborators, so add Bi / (1+i) t0 += Bi / (1.0L + (long double)i); // This collaborator's Ai is already satisfied (Bi >= Ai), so remove its Ai from the pool if still present. int p = pos[idx]; // check if still present (count at p might be 1) // safe to always attempt to remove; but need to ensure we only remove once // We'll query count prefix and single index count: // get count at single index by cntPrefix(p) - cntPrefix(p-1) int cntAt = fw.cntPrefix(p) - fw.cntPrefix(p-1); if(cntAt > 0){ fw.add(p, - (long double)allA[p-1].first, -1); } } // print with required format; error tolerance <= 0.01 cout.setf(std::ios::fixed); cout<<setprecision(12); double out = (double)ans; cout << out << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...