1 条题解
-
1
“你可能需要考虑答案是否一定是整数……” ?
答案一定为整数。
每次运输只有两种选择,直接走,距离为或者从到再从到,距离为。
设为最终选择走传送门的牛粪运输集合,总距离取决于,为中的中位数时最优。因此一定可以为整数,答案一定为整数,且的取值范围大小为。
我们作关于的图像,发现它仅由四条直线拼接而成,因此可以枚举,用优先队列直接维护。
这个东西也可以分别对每一次运输考虑,对建线段树维护。
#include<bits/stdc++.h> using namespace std; #define int long long #define lb(x) x&(-x) #define ls(p) (p<<1) #define rs(p) ((p<<1)|1) #define pii pair<int,int> #define F first #define S second #define mkp make_pair const int mod=998244353; const int N=1e5+1000,V=1e8,inf=1e15; int ans=0; bool cmp(pii x,pii y){ return x.S<y.S; } priority_queue<pii ,vector<pii >,greater<pii > >pq1,pq2,dt1; int delt,n; pii p[N]; signed main(){ ios::sync_with_stdio(0); cin.tie(0); cin>>n; for(int i=1;i<=n;i++){ cin>>p[i].F>>p[i].S; }sort(p+1,p+n+1,cmp); for(int i=1;i<=n;i++){ pq1.push(mkp(abs(p[i].F)+abs(p[i].S-(-V))-abs(p[i].F-p[i].S),i)); ans=ans+abs(p[i].S-p[i].F);//初始时,均为第一段平线 } p[0].S=-V; int rans=ans; for(int i=1;i<=n;i++){ int Y=p[i].S; delt+=(p[i].S-p[i-1].S); int ndt=(p[i].S-p[i-1].S); ans=ans-ndt*(n-i+1-pq1.size()+dt1.size())+ndt*pq2.size(); while(!pq1.empty()){//维护第一段斜线 if(!dt1.empty()&&dt1.top()==pq1.top()){ dt1.pop();pq1.pop(); }else{ if(pq1.top().F-delt<0){ int id=pq1.top().S; ans=ans+pq1.top().F-delt; pq1.pop(); }else break; } } if(abs(p[i].F)+abs(p[i].S-Y)<abs(p[i].F-p[i].S)){//维护第二段斜线 pq2.push(mkp(-abs(p[i].F)-abs(p[i].S-Y)+abs(p[i].F-p[i].S)+delt,i)); }else{ dt1.push(mkp(abs(p[i].F)+abs(p[i].S-(-V))-abs(p[i].F-p[i].S),i)); } while(!pq2.empty()){//维护第二段平线 if(pq2.top().F-delt<0){ ans=ans+pq2.top().F-delt; pq2.pop(); }else break; } rans=min(rans,ans); } cout<<rans<<"\n"; return 0; }
信息
- ID
- 812
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- (无)
- 递交数
- 74
- 已通过
- 6
- 上传者