JZOJ 3731. 【NOIP2014模拟7.10】庐州月
来源:互联网 发布:保险网络增员话术 编辑:程序博客网 时间:2024/04/30 07:41
Description
【引子】
桥上的恋人入对出双
桥边红药叹夜太漫长
月也摇晃人也彷徨
乌蓬里传来了一曲离殇
庐州月光洒在心上
月下的你不复当年模样
太多的伤难诉衷肠
叹一句当时只道是寻常
庐州月光梨花雨凉
如今的你又在谁的身旁
家乡月光深深烙在我心上
却流不出当年泪光——Vae《庐州月》
【问题描述】
小 G 是出生在庐州的一位同学,当他高中毕业后,回到了自己的家乡。然而家乡已不复当年模样,在高中表现优秀的小G 决定承担起家乡的一件重任,那就是修理已经破烂不堪的石桥。
家乡中共有n 个石桥等待修理,对于第i 个石桥,我们定义两个参数pi,vi,其中pi表示修理石桥的最小花费值,vi表示石桥需要的最小美化需求度。今天,小G 已了解到修理厂共有m 种不同的修理原料,对于第i 种原料,可以对任意
一个石桥的美化度增加di,当然这也需要花费hi的费用。由于发货场的修理原料有限,对于任意一种修理原料,只有一件,也就是说小G 只能选择购买和不购买,对于第i 种修理材料能成功修理第j 个石桥的条件是:当且仅当hi ≥ pj,di ≥vj。现在,已知这n 个石桥修理的最小花费值,最小美化需求度,以及m种修理原料的费用,可对石桥增加的美化度值,请你帮助小G完成这个修理任务。
Input
第一行包括两个正整数,n,m。
接下来 n 行中,每行包括两个正整数pi,vi。
接下来 m行中,每行包括两个正整数hi,di。
Output
只有一个整数,为最小修理花费。如果无法完成修理任务,则输出一个整数
-1。
Sample Input
2 3
2 3
5 9
3 10
3 5
6 11
Sample Output
9
【样例说明】
其中一种可行的方案是:使用第1 种材料,修理第1 个石桥,使用第3 种材
料,修理第2 个石桥,最小修理花费为3 + 6 = 9。
Data Constraint
Solution
这是一道典型的贪心题!
把石桥和修理方法都按美化需求度从大到小排序,一个一个石桥修理。
那么维护两个指针,对于一个石桥,就能知道“可能”可以修理的那些方案。
之后,排除掉之前已经选过的那些,其中必有一个最佳方案。
显然, 最佳的一定是花费大于等于当前石桥且其花费最小的!
可是维护这样的集合有一些困难,复杂度一般为
O(NlogN) 这样再加上扫描本身的
O(N) ,是会时间超限的。于是我们的平衡树算法——Splay,就隆重登场了!
只需基本的插入、删除和求后继操作就可以在
O(logN) 内实现了。
Code
#include<cstdio>#include<algorithm>using namespace std;const int N=100001;struct data{ int x,y;}a[N],b[N];int root,tot;int s[N][2],fa[N],key[N];long long ans;inline int read(){ int data=0; char ch=0; while(ch<'0' || ch>'9') ch=getchar(); while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar(); return data;}inline bool cmp(data a,data b){ return a.y>b.y;}inline bool pd(int x){ return x==s[fa[x]][1];}inline void rotate(int x){ int y=fa[x],w=pd(x); if(fa[x]=fa[y]) s[fa[y]][pd(y)]=x; fa[s[y][w]=s[x][w^1]]=y; s[fa[y]=x][w^1]=y;}inline void splay(int x){ for(int y;y=fa[x];rotate(x)) if(fa[y]) rotate(pd(x)==pd(y)?y:x); root=x;}inline int search(int x,int v){ while(key[x]!=v) if(v<key[x]) { if(!s[x][0]) break; x=s[x][0]; }else { if(!s[x][1]) break; x=s[x][1]; } return x;}inline void ins(int &x,int y,int v){ if(!x) { x=++tot; key[x]=v; fa[x]=y; return; } ins(s[x][key[x]<=v],x,v);}inline void del(int v){ int k=search(root,v); splay(k); if(!s[k][0]) { fa[root=s[k][1]]=0; key[k]=s[k][1]=0; return; } fa[s[k][0]]=0; splay(search(s[k][0],1e9)); if(s[root][1]=s[k][1]) fa[s[root][1]]=root; key[k]=s[k][0]=s[k][1]=0;}inline int find(int v){ if(!root) return 0; int x=root; while(true) { if(key[x]<v) { if(!s[x][1]) return 0; x=s[x][1]; continue; } if(s[x][0]) { int y=s[x][0]; while(key[y]<v && s[y][1]) y=s[y][1]; if(key[y]>=v) { x=y; continue; } } return x; }}int main(){ int n=read(),m=read(); for(int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(); for(int i=1;i<=m;i++) b[i].x=read(),b[i].y=read(); sort(a+1,a+1+n,cmp); sort(b+1,b+1+m,cmp); for(int i=1,j=1;i<=n;i++) { while(j<=m && b[j].y>=a[i].y) { ins(root,0,b[j++].x); splay(tot); } int k=find(a[i].x); if(!k) { printf("-1"); return 0; } ans+=key[k]; del(key[k]); } printf("%lld",ans); return 0;}
- JZOJ 3731. 【NOIP2014模拟7.10】庐州月
- JZOJ NOIP2014模拟 8.12
- JZOJ NOIP2014模拟 8.13
- jzoj NOIP2014提高组模拟8.9总结
- [JZOJ 3794]. 【NOIP2014模拟8.20】高级打字机
- 【JZOJ】 【NOIP2014】【模拟试题】保镖排队
- JZOJ 3808. 【NOIP2014模拟8.25】道路值守
- JZOJ 3807. 【NOIP2014模拟8.25】地砖铺设
- JZOJ 3807. 【NOIP2014模拟8.25】地砖铺设
- JZOJ 3809. 【NOIP2014模拟8.25】设备塔
- JZOJ 3809. 【NOIP2014模拟8.25】设备塔
- JZOJ 3814. 【NOIP2014模拟9.7】天黑黑
- JZOJ 3823. 【NOIP2014模拟9.9】遇见
- JZOJ 3822. 【NOIP2014模拟9.9】逆光
- JZOJ 3823【NOIP2014模拟9.9】遇见
- JZOJ 3824【NOIP2014模拟9.9】渴
- 【JZOJ 3823】【NOIP2014模拟9.9】遇见
- JZOJ 3839【NOIP2014模拟9.14】Baby Step
- 简单的客户端,服务端通信
- 【数据压缩】调用VFW库对无压缩avi的解封装
- 线程创建
- Linux 链接脚本分析
- 新三板挂牌条件是什么?
- JZOJ 3731. 【NOIP2014模拟7.10】庐州月
- C#定时程序
- ASP页面添加打印按钮
- python中类的基本使用
- 【bzoj1002】[FJOI2007]轮状病毒
- 如何关掉Java里面的window边框
- keras中merge用法
- keras中Convolution1D的使用
- python中使用文件的读取编码问题和简单正则使用(一)