【noip模拟】D(==)
Portal --> who knows ==
Description
数轴上面有一些洞,有一些老鼠,每个洞有一个容量限制,一只位于\(x\)的老鼠进到位于\(y\)的洞要花费\(|x-y|\)的代价,问所有老鼠都进洞的最小代价,如果没有合法方案输出\(-1\)
数据范围:\(n,m<=10^6,1<=c_i<=n\),其中\(c_i\)表示每个洞的容量,\(0<=\)位置\(<=10^9\)
Solution
这题的话。。长得像一个dp。。但是如果直接莽显然是不行的。。
注意到一个点:将洞和老鼠都按照位置排序,最优方案中进入同一个洞的老鼠一定是一段连续的区间,那么记\(f[i][j]\)表示前\(i\)个洞,前\(j\)只老鼠已经进洞了的最小代价,转移的话:
\]
其中\(k\)的枚举范围是\([j-c[i],j]\),\(sum[j]\)表示的是\(\sum\limits_{p=1}^j|rat_p-hole_i|\)
那么线段树优化一下就有一个\(O(nmlogn)\)的做法(然而实际上好像直接单调栈什么的搞一搞除去排序就是\(O(nm)\)了)
然后注意到这个dp是没有前途的。。(没有办法继续优化了),所以换一种思路
不选择分开考虑,而是选择将所有的老鼠和洞放在一起,这里有一种很妙的用堆的做法(疯狂orzhwc),用两个堆分别维护老鼠和洞
我们将老鼠和洞放在一条线上,一只老鼠要么会被丢到前面,要么会被丢到后面,那么我们从左往右扫,考虑如果扫到一只老鼠,我们先无脑将它丢到它前面的离它最近的有容量的洞里面,更优情况的替换我们放在扫到一个洞的时候处理
扫到一个洞的时候,如果说有只当前被丢到前面洞里的老鼠丢到这个洞里面会比当前更优,那么就把这只老鼠丢进来,更新当前答案,具体的判断方式是:我们将前面的那个洞的位置以当前老鼠为对称轴对称过来,如果说对称过来得到的位置比当前洞的位置更大,那么说明当前洞更优
具体处理的话就是用一个堆维护被丢进前面的洞里的老鼠对应的洞的对称值(也就是\(rat+hole\),其中\(rat\)表示这只老鼠的位置,\(hole\)表示对应洞的位置),然后如果堆顶的那个老鼠不能被当前这个洞更新,那肯定也不能被后面的洞更新了,所以直接弹掉
然而这里有一个问题,当前的决策放在后面不一定是最优的,也就是说有的老鼠当前可能丢到后面比较优,但是放在全局可能就是丢到前面比较优了,为了应对这种情况,我们需要一个撤销操作,具体的实现就是,如果说在扫到一个洞的时候,我们用这个洞更新了某只老鼠,那么对应的我们要多加一个相当于撤销操作的洞到洞的堆里面,撤销的具体含义就是:如果说当前的老鼠选了一个撤销洞,那么就相当于令被撤销洞更新的老鼠重新回到更新前的洞里,并且将当前的老鼠丢到这个洞里
实现上的话,假设撤销洞位置为\(y\),被撤销洞更新的老鼠\(A\)在更新前在的洞是\(x\),\(delta\)是该老鼠选\(y\)比选\(x\)优多少,那么撤销洞的位置就应该为\(y+delta\),并且容量为\(1\),之所以这么设是因为:如果说当前的老鼠\(B\)选了这个洞,那么\(ans\)会被加上\(rat_B-(y+delta)\),也就是相当于将\(delta\)去掉(老鼠\(A\)回到\(x\)),然后再加上老鼠\(B\)选\(y\)这个洞的贡献
然后一路扫过去就好了ovo
mark:撤销洞的思路很有意思,mark一下
代码大概长这个样子
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define ll long long
#define Pr pair<ll,int>
#define mp make_pair
using namespace std;
const int N=1000010;
const ll inf=1LL<<60;
struct Data{
int p,c,ty;
friend bool operator < (Data x,Data y){
return x.p==y.p?x.ty<y.ty:x.p<y.p;
}
}a[N*2];
priority_queue<Pr> hole;
priority_queue<ll> rat;
int n,m,cnt;
ll ans;
void solve_rat(int i){
ll w=inf;
Pr tmp;
if (!hole.empty()){
tmp=hole.top(); hole.pop();
w=a[i].p-tmp.first;
--tmp.second;
if (tmp.second)
hole.push(tmp);
}
rat.push(w+a[i].p);
ans+=w;
}
void solve_hole(int i){
ll delta;
while (a[i].c&&!rat.empty()&&a[i].p<rat.top()){
delta=a[i].p-rat.top(); rat.pop();
ans+=delta;
--a[i].c;
hole.push(mp(a[i].p+delta,1));
}
if (a[i].c)
hole.push(mp(a[i].p,a[i].c));
}
void solve(){
for (int i=1;i<=cnt;++i)
if (a[i].ty==0)
solve_rat(i);
else
solve_hole(i);
printf("%lld\n",ans);
}
void print(Pr x){printf("(%d,%d)\n",x.first,x.second);}
int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
int x,y;
ll sum=0;
scanf("%d%d",&n,&m);
cnt=0;
for (int i=1;i<=n;++i) scanf("%d",&a[++cnt].p),a[cnt].ty=0;
for (int i=1;i<=m;++i){
scanf("%d%d",&x,&y);
if (!y) continue;
a[++cnt].p=x; a[cnt].c=y; a[cnt].ty=1;
sum+=y;
}
if (sum<n){printf("-1\n"); return 0;}
sort(a+1,a+1+cnt);
solve();
}
【noip模拟】D(==)的更多相关文章
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...
- 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...
- 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- CH Round #52 - Thinking Bear #1 (NOIP模拟赛)
A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...
- CH Round #49 - Streaming #4 (NOIP模拟赛Day2)
A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...
随机推荐
- Streamr助你掌控自己的数据(1)——教你5分钟上传数据至Streamr
博客说明 所有刊发内容均可转载但是需要注明出处. 教你5分钟上传数据至Streamr 本系列文档主要介绍怎么通过Streamr管理自己的DATA,整个系列包括三篇教程文档,分别是:教你5分钟上传数据至 ...
- Python字典 (dict)
作者博文地址:http://www.cnblogs.com/spiritman/ 字典是Python语言中唯一的映射类型.字典对象是可变的,它是一个容器类型,支持异构.任意嵌套. 创建字典 语法:{k ...
- python的Socket网络编程 使用模板
本文给出的是TCP协议的Socket编程. 其中用了一个dbmanager数据库操作模块,这个模块是我自己定义的,可以在我的另一个文章中找到这个模块的分享.python操作mysql数据库的精美实用模 ...
- 测试效率 timeit cProfile
timeit使用 def f1(lIn): l1 = sorted(lIn) # O(nlogn) C语言的 l2 = [i for i in l1 if i<0.5] # O(n) retur ...
- js为一个对象Object添加一个新的属性和值
1, var obj = {}; //或者 var obj=new Object(); var key = "name"; var value = "张三丰" ...
- Sprint会议2
昨天:准备查找安卓APP开发的有关资料,安装有关软件 今天:自己制作一个安卓小程序,熟悉一下操作 遇到问题:安装遇到问题,环境配置出现问题
- JAVA对象的初始化过程
出处:http://blog.csdn.net/andrew323/article/details/4665379 下面我们通过两个例题来说明对象的实例化过程. 例1: 编译并运行该程序会有以下输 ...
- [BUAA_SE_2017]个人阅读作业 + 总结
个人阅读作业 银弹 银弹是指能让狼人一枪毙命的致命子弹,对于软件工程而言,我觉得是不存在银弹的.每一项软件开发都是极为特殊的,有特定的需求.特定的功能,如果存在银弹能够直击要害解决问题,那么软件的开发 ...
- maven编译,控制台中文乱码解决方案
如下图,在使用maven运行后,在控制台看到中文展示乱码 出现这个的原因是源码使用UTF-8,但是maven编译的时候使用GBK标准,如下图 为了让maven编译的时候使用UTF-8标准,使用在p ...
- linux使用密文生成os账户
1.生成账户 [hufangrui@xxx ~]$ openssl passwd -1Password: Verifying - Password: $1$szzkROBZ$GYxffRLp8K5vW ...