abc373E How to Win the Election
有N个候选人和总共K张选票,目前第i个候选人的票数为A[i]。在全部选票统计完成后,如果得票数多于自己的人数小于M,则当选,可以多个人同时当选。对于每个人,输出当选需要再获得的最少票数。
1<=M<=N<=2E5, 1<=K<=1E12, 0<=A[i]<=1E12, sum(A[i])<=K
分析:对每个候选人,二分答案,假设需要的票数为x,那么最终得票为A[i]+x,大于该得票的人数记为P,则需要统计另外M-P个人的票数进行补齐,看剩下的票数是否足够。
#include <bits/stdc++.h> using i64 = long long; // SumTreap模板... void solve() { i64 N, M, K; std::cin >> N >> M >> K; SumTreap<i64> tr; std::vector<i64> A(N); for (int i = 0; i < N; i++) { std::cin >> A[i]; tr.insert(A[i]); K -= A[i]; } if (N == M) { for (int i = 0; i < N; i++) { std::cout << " 0"; } return; } auto check = [&](i64 cur, i64 add) { i64 tar = cur + add; int cnt1 = tr.gtcnt(tar); if (cnt1 >= M) { return false; } int cnt2 = M - cnt1; i64 sum2 = tr.kSum(M) - tr.kSum(cnt1); i64 diff = cnt2 * (tar + 1) - sum2; return diff + add > K; }; std::vector<i64> ans(N); for (int i = 0; i < N; i++) { tr.erase(A[i]); i64 lo = 0, hi = 1E12, mid; while (lo < hi) { mid = lo + (hi - lo) / 2; if (check(A[i], mid)) { hi = mid; } else { lo = mid + 1; } } if (lo <= K) { ans[i] = lo; } else { ans[i] = -1; } tr.insert(A[i]); } for (int i = 0; i < N; i++) { std::cout << ans[i] << " "; } } int main() { std::cin.tie(0)->sync_with_stdio(0); int t = 1; while (t--) solve(); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】