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\)只老鼠已经进洞了的最小代价,转移的话:

\[f[i][j]=min(f[i-1][k]+sum[j]-sum[k])
\]

  其中\(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(==)的更多相关文章

  1. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  2. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  3. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  4. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  5. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  6. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  7. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

  8. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

  9. CH Round #52 - Thinking Bear #1 (NOIP模拟赛)

    A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...

  10. CH Round #49 - Streaming #4 (NOIP模拟赛Day2)

    A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...

随机推荐

  1. 铁轨(rails, ACM/ICPC CERC 1997,Uva 514)

    铁轨(rails, ACM/ICPC CERC 1997,Uva 514) 题目描述 某城市有一个火车站,铁轨铺设如图所示.有n节车厢从A方向驶入车站,按进站顺序编号为1~n.你的任务是让它们按照某种 ...

  2. Linux下端口映射工具rinetd

    Linux下简单好用的工具rinetd,实现端口映射/转发/重定向官网地址http://www.boutell.com/rinetd 软件下载wget http://www.boutell.com/r ...

  3. Redis Jedis简介

    Redis是一种基于内存类型的数据存储工具 Jedis是一个用java写的Redis数据库操作的客户端,通过Jedis,可以很方便的对redis数据库进行操作.Jedis通过Jedis Pool进行R ...

  4. chown命令详情

    基础命令学习目录首页 原文链接:https://www.jb51.net/article/98255.htm chown将指定文件的拥有者改为指定的用户或组,用户可以是用户名或者用户ID:组可以是组名 ...

  5. Linux(Red hat)无网离线安装TensorFlow

    文件下载 首先,下载想要安装的版本,目前最新的是1.8.0 根据你的python版本下载对应的whl文件,下载连接:https://pypi.org/project/tensorflow/#files ...

  6. JVM的GC策略

    1 前言 GC(Garbage Collect)是jvm对于内存管理的核心功能,正是因为它才让Java程序员从内存释放的苦海中脱离出来,所以作为一个程序员都有必要去了解一下他的原理. 说一句题外话,我 ...

  7. MySql点点滴滴(一)之可视化工具介绍

    以下的文章主要介绍的是10个可以简化开发过程的MySQL工具,其中包括MySQL Workbench.phpMyAdmin.Aqua Data Studio,以及SQLyog与MYSQL Front等 ...

  8. jQuery扩展插件

    jQuery有多好用,大家有目共睹的,但是有时候不是每个功能都是万能的,有时候我们需要实现自己的功能,jQuery提供了很好的拓展功能,我们可以去拓展插件,更好的利用jQuery 查看官网,可知,有两 ...

  9. 搭建企业级Docker Registry -- Harbor

    Harbor 是一个企业级的 Docker Registry,可以实现 images 的私有存储和日志统计权限控制等功能,并支持创建多项目(Harbor 提出的概念),基于官方 Registry V2 ...

  10. “Unable to open kernel device \\.\Global\vmx86

    启动vm中虚拟机中的时候,弹出窗口的时候,弹出窗口 Unable to open kernel device \\.\Global\vmx86;系统找不到指定的文件,Did you reboot af ...