【题解】Berland.Taxi Codeforces 883L 模拟 线段树 堆
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 模拟 线段树 堆的更多相关文章
- 【题解】P1712 [NOI2016]区间(贪心+线段树)
[题解]P1712 [NOI2016]区间(贪心+线段树) 一个observe是,对于一个合法的方案,将其线段长度按照从大到小排序后,他极差的来源是第一个和最后一个.或者说,读入的线段按照长度分类后, ...
- Codeforces 765F Souvenirs 线段树 + 主席树 (看题解)
Souvenirs 我们将询问离线, 我们从左往右加元素, 如果当前的位置为 i ,用一棵线段树保存区间[x, i]的答案, 每次更新完, 遍历R位于 i 的询问更新答案. 我们先考虑最暴力的做法, ...
- CodeForces 91B Queue (线段树,区间最值)
http://codeforces.com/problemset/problem/91/B B. Queue time limit per test: 2 seconds memory limit p ...
- Codeforces 343D WaterTree - 线段树, DFS序
Description Translated by @Nishikino_Maki from Luogu 行吧是我翻的 Mad scientist Mike has constructed a roo ...
- 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 最 ...
- Vasya and a Tree CodeForces - 1076E(线段树+dfs)
I - Vasya and a Tree CodeForces - 1076E 其实参考完别人的思路,写完程序交上去,还是没理解啥意思..昨晚再仔细想了想.终于弄明白了(有可能不对 题意是有一棵树n个 ...
- BZOJ4946[Noi2017]蔬菜——线段树+堆+模拟费用流
题目链接: [Noi2017]蔬菜 题目大意:有$n$种蔬菜,每种蔬菜有$c_{i}$个,每种蔬菜每天有$x_{i}$个单位会坏掉(准确来说每天每种蔬菜坏掉的量是$x_{i}-$当天这种蔬菜卖出量), ...
- ACM-ICPC 2018 南京赛区网络预赛 G Lpl and Energy-saving Lamps(模拟+线段树)
https://nanti.jisuanke.com/t/30996 题意 每天增加m个灯泡,n个房间,能一次性换就换,模拟换灯泡过程.询问第几天的状态 分析 离线做,按题意模拟.比赛时线段树写挫了. ...
- 题解——洛谷P2781 传教(线段树)
可以说是数据结构学傻了的典型案例了 昨天跳到这题上 然后思考了一下 噫!好!线段树裸题 然后打完板子,发现\( n \le 10^9 \) 显然线段树直接做不太行 然后这题又只有普及的难度 然后我就 ...
随机推荐
- AirSim的搭建和使用
由于自己使用设备拍摄的数据质量太差,所以决定使用AirSim这个框架来生成数据.之所以使用这个框架,是因为之前同事用其生成了一些有效数据. 当然,我是不可能把我搭建的步骤一一写出来的,一来是因为太麻烦 ...
- Twitter推广消息可使品牌线下销售额增长三成
新浪科技讯 北京时间8月9日上午消息,Twitter周四宣布,该公司的推广消息(Promoted Tweet)可以让品牌的线下销售增长29%. 此外,Twitter当天还推出了一个新项目,让品牌可以追 ...
- SAP(ABAP) ABAP内部外部数据转换常用function
文本相关CONVERSION_EXIT_CUNIT_OUTPUT 将内部单位转为单位文本CONVERSION_EXIT_ISOLA_OUTPUT 根据语言代码取文本CONVERSI ...
- 7. I/O复用
一.I/O复用的特点 能同时监听多个文件描述符 自身是阻塞的 当多个文件描述符同时就绪时,如果不采取额外的措施,程序就只能按顺序依次处理其中的每一个文件描述符 由于其第三个特点,所以服务器程序看起来仍 ...
- Leftmost Digit(数学)
Description Given a positive integer N, you should output the leftmost digit of N^N. Input The inp ...
- lintcode-473-单词的添加与查找
473-单词的添加与查找 设计一个包含下面两个操作的数据结构:addWord(word), search(word) addWord(word)会在数据结构中添加一个单词.而search(word)则 ...
- jQuery之回到顶部
实现回到顶部的功能,根据学了元素滚动实现,温习知识点. 做之前先理清一下步骤和思路: 1.获得页面的滚动长度 var $page = $("html,body"); var dis ...
- 【beta】Scrum站立会议第5次....11.7
小组名称:nice! 组长:李权 成员:于淼 刘芳芳韩媛媛 宫丽君 项目内容:约跑app(约吧) 时间:2016.11.7 12:00——12:30 地点:传媒西楼220室 本次对beta阶段的 ...
- PAT 甲级 1019 General Palindromic Number
https://pintia.cn/problem-sets/994805342720868352/problems/994805487143337984 A number that will be ...
- PHP中面向对象编程思想的3个特征
面向对象编程思想的3个特征: 封装: 无非是一个大的指向思想,目的是为了将一个类设计得更为健壮! 其基本做法是: 尽可能地将一个类的成员私有化,只开放那些必不可少的对外的属性或方法,能private的 ...