【JZO5271】【GDOI2018模拟8.14】神奇的救火现场
2017-08-21 22:54
489 查看
Description
Data Constraint
Solution
这和以前的jzoj上一道叫保持平衡的题很像啊。当然也有线性的做法,但我们这里只讲一下NlogN的做法。我们维护两个小根堆分别为水栓和车的供给代价。每遇到一辆车,若水栓不为空,我们从水栓的堆中取出最小的代价x与其坐标相加后加入答案,并将坐标取反-代价加入车堆,若水栓为空,我们则将代价设为+∞重复刚才操作,表示以后若有水栓优先供应给这辆车。每遇到一个水栓,我们都在车里找一个最小答案,若最小答案小于0则加入答案并将坐标取反-代价加入水栓中。否则直接坐标取反加入即可。
Code
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #include<set> #define ll long long using namespace std; const ll maxn=3e5+5,mo=0x7fffffff; multiset<ll>f,g; struct code{ ll x,bz; }a[maxn]; ll n,m,i,t,j,k,l,x,y,z,ans; bool cmp(code x,code y){ return x.x<y.x; } int main(){ freopen("fire.in","r",stdin);freopen("fire.out","w",stdout); scanf("%lld%lld",&m,&n); for (i=1;i<=m;i++)scanf("%lld",&a[i].x); for (i=1;i<=n;i++)scanf("%lld",&a[m+i].x),a[m+i].bz=1; n+=m; sort(a+1,a+n+1,cmp); for (i=1;i<=n;i++) if (a[i].bz){ if (!f.empty()){ x=*f.begin(); t=a[i].x+x; ans+=t; g.insert(-t-a[i].x); f.erase(f.begin()); }else{ ans+=mo; g.insert(-mo-a[i].x); } }else{ if (!g.empty()){ x=*g.begin(); if (x+a[i].x<0) g.erase(g.begin()); else x=-a[i].x; }else x=-a[i].x; t=a[i].x+x; ans+=t; f.insert(-t-a[i].x); } printf("%lld\n",ans); }
相关文章推荐
- 【GDOI2018模拟8.14】神奇的救火现场
- 【JZOJ5270】【GDOI2018模拟8.14】神奇的矩阵
- 【GDOI2018模拟8.14】神奇的矩阵
- 【JZOJ5272】【GDOI2018模拟8.14】神奇的重复序列
- 【JZOJ5270】【GDOI2018模拟】神奇的矩阵(二维线段树)
- 【JZOJ5272】【GDOI2018模拟】神奇的重复序列(DP,性质题)
- 【GDOI2018模拟7.9】组合数问题
- 【GDOI2018模拟7.8】矩阵
- 【jozj5228】【GDOI2018模拟7.14】【小奇的集合】【矩阵乘法】
- [bzoj4548]【GDOI2018模拟7.14】小奇的糖果
- 【JZOJ 5241】【GDOI2018模拟8.8】苹果和雪梨
- JZOJ5220. 【GDOI2018模拟7.10】C(2017.8DP&贪心专题)
- 【GDOI2018模拟8.12】区间第k小
- 【JZOJ5219】【GDOI2018模拟7.10】B
- JZOJ 5221. 【GDOI2018模拟7.10】A
- 【JZOJ 5204】【GDOI2018模拟7.6】吃干饭
- 【jzoj5237】【GDOI2018模拟8.7】【最长公共子序列 】【动态规划】
- 【GDOI2018模拟8.12】区间第k小
- 【JZOJ5220】【GDOI2018模拟7.10】C
- 【JZOJ5222】【GDOI2018模拟7.12】A