Link:
可能要补一补之前的题了
题目名字天(Sky)的(De)炭(C)好评啊……
A:
从买/卖物品的配对来考虑:
可以发现如果当前物品为卖,肯定从之前选最小的(无论其为买/卖),因为贡献都是差值!
如果要买的物品当前状态为卖,那么相当于将那条匹配链的卖的那一端转换
用优先队列维护$pair(w[i],0/1)$,0/1分别表示当前为卖/买的状态即可
#include <bits/stdc++.h> using namespace std; #define X first #define Y second typedef long long ll; typedef pair<int,int> P; const int MAXN=1e5+10; int T,n,cnt,dat[MAXN];ll res=0; priority_queue<P,vector<P>,greater<P> > q; int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&dat[i]); res=0;cnt=0; while(!q.empty()) q.pop(); q.push(P(dat[1],1)); for(int i=2;i<=n;i++) { P t=q.top(); if(dat[i]>t.X) { res+=dat[i]-t.X; cnt+=t.Y;q.pop(); if(!t.Y) q.push(P(t.X,1)); q.push(P(dat[i],0)); } else q.push(P(dat[i],1)); } printf("%lld %d\n",res,cnt*2); } return 0; }