Prelude

题目传送门:ヾ(•ω•`)o


Solution

按照题意模拟即可。

维护一个优先队列,里面装的是正在运营中的出租车,关键字是乘客的下车时间。

维护一个线段树,第\(i\)个位置表示第\(i\)个房子前面有没有停放出租车,这样在有人需要打车的时候可以快速找到离她最近的车的位置。

对每个房子维护一个堆,里面装的是停在这个房子前面的出租车,关键字是出租车的编号和上一个乘客下车的时间,上一个乘客下车越早,等待时间越长。

然后模拟时间的流逝就可以了,代码非常好写。


Code

#include <cstring>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <utility>
#include <cstdlib>
#include <cassert> using namespace std;
typedef long long ll;
const int MAXN = 200010;
const int INF = 0x3f3f3f3f;
int _w; int n, k, m, x[MAXN], a[MAXN], b[MAXN];
ll t[MAXN]; namespace SGT {
int sumv[MAXN<<2], ql, qr, qv;
void _add( int o, int L, int R ) {
sumv[o] += qv;
if( L == R ) return;
int M = (L+R)/2, lc = o<<1, rc = lc|1;
if( ql <= M ) _add(lc, L, M);
else _add(rc, M+1, R);
}
void add( int p, int v ) {
ql = p, qv = v;
_add(1, 1, n);
}
void _queryl( int o, int L, int R ) {
if( L >= ql && R <= qr ) {
if( !sumv[o] ) return;
while( L != R ) {
int M = (L+R)/2, lc = o<<1, rc = lc|1;
if( sumv[lc] ) o = lc, R = M;
else o = rc, L = M+1;
}
qv = L;
} else {
int M = (L+R)/2, lc = o<<1, rc = lc|1;
if( ql <= M && !qv ) _queryl(lc, L, M);
if( qr > M && !qv ) _queryl(rc, M+1, R);
}
}
int queryl( int l, int r ) {
ql = l, qr = r, qv = 0;
_queryl(1, 1, n);
return qv;
}
void _queryr( int o, int L, int R ) {
if( L >= ql && R <= qr ) {
if( !sumv[o] ) return;
while( L < R ) {
int M = (L+R)/2, lc = o<<1, rc = lc|1;
if( sumv[rc] ) o = rc, L = M+1;
else o = lc, R = M;
}
qv = L;
} else {
int M = (L+R)/2, lc = o<<1, rc = lc|1;
if( qr > M && !qv ) _queryr(rc, M+1, R);
if( ql <= M && !qv ) _queryr(lc, L, M);
}
}
int queryr( int l, int r ) {
ql = l, qr = r, qv = 0;
_queryr(1, 1, n);
return qv;
}
} struct Node {
ll t;
int id;
Node() {}
Node( ll t, int id ):
t(t), id(id) {}
bool operator<( const Node &rhs ) const {
return t == rhs.t ? id > rhs.id : t > rhs.t;
}
};
priority_queue<Node> pq[MAXN], evt; void prelude() {
for( int i = 1; i <= k; ++i ) {
pq[x[i]].push( Node(0, i) );
SGT::add(x[i], 1);
}
} void run( ll t ) {
while( !evt.empty() && evt.top().t <= t ) {
Node car = evt.top(); evt.pop();
SGT::add(x[car.id], 1);
// printf( "car.id = %d, x[id] = %d\n", car.id, x[car.id] );
pq[x[car.id]].push(car);
}
}
int use( int pos ) {
Node car = pq[pos].top(); pq[pos].pop();
SGT::add(pos, -1);
return car.id;
}
int freecar( int pos ) {
if( !SGT::sumv[1] ) return 0;
int left = SGT::queryr(1, pos);
int right = SGT::queryl(pos, n);
// printf( "left = %d, right = %d\n", left, right );
if( !left ) left = -INF;
if( !right ) right = INF;
if( left == right ) {
return use(left);
} else if( pos-left < right-pos ) {
return use(left);
} else if( right-pos < pos-left ) {
return use(right);
} else {
Node cl = pq[left].top(), cr = pq[right].top();
if( cl.t == cr.t ) {
if( cl.id < cr.id ) {
return use(left);
} else {
return use(right);
}
} else if( cl.t < cr.t ) {
return use(left);
} else {
return use(right);
}
}
}
void solve() {
ll now = 0;
for( int i = 0; i < m; ++i ) {
now = max(now, t[i]);
run(now);
int car = freecar( a[i] );
// printf( "now = %lld, car = %d\n", now, car );
if( !car ) {
now = max(now, evt.top().t);
run(now);
// printf( "now = %lld, car = %d\n", now, car );
car = freecar( a[i] );
}
// printf( "now = %lld, car = %d\n", now, car );
printf( "%d %lld\n", car, now - t[i] + abs(x[car] - a[i]) );
evt.push( Node(now + abs(x[car] - a[i]) + abs(a[i] - b[i]), car) );
x[car] = b[i];
}
} int main() {
_w = scanf( "%d%d%d", &n, &k, &m );
for( int i = 1; i <= k; ++i )
_w = scanf( "%d", x+i );
for( int i = 0; i < m; ++i )
_w = scanf( "%lld%d%d", t+i, a+i, b+i );
prelude(), solve();
return 0;
}

【题解】Berland.Taxi Codeforces 883L 模拟 线段树 堆的更多相关文章

  1. 【题解】P1712 [NOI2016]区间(贪心+线段树)

    [题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...

  2. Codeforces 765F Souvenirs 线段树 + 主席树 (看题解)

    Souvenirs 我们将询问离线, 我们从左往右加元素, 如果当前的位置为 i ,用一棵线段树保存区间[x, i]的答案, 每次更新完, 遍历R位于 i 的询问更新答案. 我们先考虑最暴力的做法, ...

  3. CodeForces 91B Queue (线段树,区间最值)

    http://codeforces.com/problemset/problem/91/B B. Queue time limit per test: 2 seconds memory limit p ...

  4. Codeforces 343D WaterTree - 线段树, DFS序

    Description Translated by @Nishikino_Maki from Luogu 行吧是我翻的 Mad scientist Mike has constructed a roo ...

  5. codeforces 787D - Legacy 线段树优化建图,最短路

    题意: 有n个点,q个询问, 每次询问有一种操作. 操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w: 操作2:[l,r]→u的距离为w 操作3:u到v的距离为w 最 ...

  6. Vasya and a Tree CodeForces - 1076E(线段树+dfs)

    I - Vasya and a Tree CodeForces - 1076E 其实参考完别人的思路,写完程序交上去,还是没理解啥意思..昨晚再仔细想了想.终于弄明白了(有可能不对 题意是有一棵树n个 ...

  7. BZOJ4946[Noi2017]蔬菜——线段树+堆+模拟费用流

    题目链接: [Noi2017]蔬菜 题目大意:有$n$种蔬菜,每种蔬菜有$c_{i}$个,每种蔬菜每天有$x_{i}$个单位会坏掉(准确来说每天每种蔬菜坏掉的量是$x_{i}-$当天这种蔬菜卖出量), ...

  8. ACM-ICPC 2018 南京赛区网络预赛 G Lpl and Energy-saving Lamps(模拟+线段树)

    https://nanti.jisuanke.com/t/30996 题意 每天增加m个灯泡,n个房间,能一次性换就换,模拟换灯泡过程.询问第几天的状态 分析 离线做,按题意模拟.比赛时线段树写挫了. ...

  9. 题解——洛谷P2781 传教(线段树)

    可以说是数据结构学傻了的典型案例了 昨天跳到这题上 然后思考了一下 噫!好!线段树裸题 然后打完板子,发现\(  n \le 10^9 \) 显然线段树直接做不太行 然后这题又只有普及的难度 然后我就 ...

随机推荐

  1. DOM---文档对象模型(Document Object Model)的基本使用

    一.DOM简介 文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口.它是一种与平台和语言无关的应用程序接口(API),它可以动态 ...

  2. Qt类继承关系图

    分享两个资源,对于系统了解Qt框架的整体脉络很有帮助. Qt4类关系图+Qt5类关系图,PDF+JPG格式 [下载] Qt5类关系图(基于Qt5.1版),JPG格式[下载]

  3. 到底什么是BFC、IFC、GFC和FFC,次奥?

    软件开发的一般被称为民工,搞前端的,有人形容为是掏粪工,说白了连民工级别高都没有.说直接点就是个制作界面的,注意,连设计界面的都算不上,一般前端都是拿着设计稿去照这样子开发的. 说这些无非是觉得前端前 ...

  4. 03 JAVA IO

    java.io包中定义了多个流类型来实现输入输出功能,以不同的角度进行分类: 按数据流的方向不同可以分为输入流和输出流 按处理数据单位不通可以分为字节流和字符流 按照功能不同可以分为节点流和处理流 所 ...

  5. 2016-2017 ACM-ICPC, NEERC, Northern Subregional Contest Problem F. Format

    题目来源:http://codeforces.com/group/aUVPeyEnI2/contest/229510 时间限制:1s 空间限制:512MB 题目大意: 给定一个字符串,使用%[...] ...

  6. Codeforces Round #287 (Div. 2) E. Breaking Good 最短路

    题目链接: http://codeforces.com/problemset/problem/507/E E. Breaking Good time limit per test2 secondsme ...

  7. HDU 5229 ZCC loves strings 博弈

    题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5229 bc:http://bestcoder.hdu.edu.cn/contests/con ...

  8. lintcode-512-解码方法

    512-解码方法 有一个消息包含A-Z通过以下规则编码 'A' -> 1 'B' -> 2 ... 'Z' -> 26 现在给你一个加密过后的消息,问有几种解码的方式 样例 给你的消 ...

  9. DB2 UDB V8.1 管理

    在DB2中有关实例(Instance), 数据库(Database),表空间(TableSpace),容器(Container)等概念: 在一个操作系统中,DB2数据服务可以同时运行多个实例(有别于O ...

  10. 【BioCode】将多个蛋白质序列分成单个的txt文档

    代码说明: fasta格式的蛋白质序列,一个txt里面有很多蛋白质序列,计算ss.pssm或disorder score时候都需要单条计算,需要分开. 分割前: 分割后: show you the c ...