題解 P7878 「SWTR-07」My rating is 1064(hard version)
阿新 • • 發佈:2021-10-02
沿用 easy version 的思路:考慮如果到目前已經放了 \(2\) 個集合及以上,那麼接下來只要輪換放置就可以避免「用同一個賬號連續發出兩個帖子」。所以在放了 \(2\) 個集合以後只要找到剩下前 \(k-2\) 大的數放即可。
於是一定是把前 \(x\) 個數放在第一個集合,第 \(x+1\) 放在第二個集合,剩下的選出前 \(k-2\) 大放在剩下集合。
然後直接倒著列舉 \(x\),用堆(priority_queue)維護剩餘的前 \(k-2\) 大的數,計算即可。
const int N=500005; int n,m,T; ll a[N]; priority_queue<ll>p; ll sum,ans; inline void add(ll x) { sum+=x; p.push(-x); ll u=-p.top(); sum-=u; p.pop(); } void work() { n=read(),m=read()-2; for (int i=1;i<=n;i++) a[i]=read(); ll tot=a[1]; sum=0; while (!p.empty()) p.pop(); for (int i=n-m+1;i<=n;i++) sum+=a[i],p.push(-a[i]); for (int i=2;i<=n-m-1;i++) tot-=min(a[i-1],a[i]); ans=tot+sum+a[n-m]; for (int i=n-m-1;i>=2;i--) { add(a[i+1]); tot+=min(a[i],a[i-1]); ans=max(ans,tot+sum+a[i]); } printf("%lld\n",ans); return; }