[bzoj3938] [Uoj #88] Robot
Description
小 \(q\) 有 \(n\) 只机器人,一开始他把机器人放在了一条数轴上,第 \(i\) 只机器人在 \(a_i\) 的位置上静止,而自己站在原点。在这之后小 \(q\) 会执行一些操作,他想要命令一个机器人向左或者向右移动 \(x\) 格。但是机器人似乎听不清小 \(q\) 的命令,事实上它们会以每秒 \(x\) 格的速度匀速移动。看着自己的机器人越走越远,小 \(q\) 很着急,他想知道当前离他(原点)最远的机器人有多远。具体的操作以及询问见输入格式。注意,不同的机器人之间互不影响,即不用考虑两个机器人撞在了一起的情况。
Input
共有 \(m\) 个事件,输入将会按事件的时间顺序给出。
第一行两个正整数 \(n\),\(m\) 。接下来一行 \(n\) 个整数,第 \(i\) 个数是 \(a_i\),表示第 \(i\) 个机器人初始的位置(初始移动速度为0)。
接下来 \(m\) 行,每行行首是一个非负整数 \(t_i\) ,表示该事件点发生的时刻(以秒为单位)。
第二个是一个字符串 \(S\),代表操作的种类。数字与字符串之间用一个空格隔开。接下来的输入按 \(S\) 的种类分类。若 \(S\) 是 \(“command”\)(不带引号),则接下来两个整数 \(k_i\) ,$ x_i$ ,表示小 \(q\) 对第 \(k_i\) 个机器人执行了操作,该机器人的速度将会被重置,变为向数轴正方向每秒移动 \(x_i\) 格(若 \(x_i\) 为负数就相当于向数轴负方向每秒移动 \(∣x_i∣\)格)。保证 \(1\leq k_i \leq n\)。若 \(S\) 是 \(“query”\)(不带引号),则你需要输出当前离原点最远的机器人有多远。
保证 $t1 \leq t2 \leq ... \leq tm $。(注:若同一时间发生多次操作,则按读入顺序依次执行)
Output
对于每个 \(query\) 询问,输出一行,包含一个整数表示正确的答案。
Sample Input
4 5
-20 0 20 100
10 command 1 10
20 command 3 -10
30 query
40 command 1 -30
50 query
Sample Output
180
280
HINT
第一个命令执行时,各个机器人的位置为:−20,0,20,100。
第二个命令执行时,各个机器人的位置为:80,0,20,100。
第一个询问时,各个机器人的位置为:180,0,−80,100。
第三个命令执行时,各个机器人的位置为:280,0,−180,100。
第二个询问时,各个机器人的位置为:−20,0,−280,100。
限制与约定
设 \(command\) 的个数为 \(C\),\(query\) 的个数为 \(Q\)。(所以 \(C+Q=m\))
对于所有的事件满足 \(0 \leq ti \leq 10^9\),对于所有的 \(command\) 满足 \(∣x_i∣ \leq 10^4\)。
对于所有的机器人满足 \(∣a_i∣ \leq 10^9\) 。
\(N,C \leq 10^5\)
\(Q \leq 5 \times 10^5\)
想法
稍稍转化一下,以时间为 \(x\) 轴,位置为 \(y\) 轴,就是一道经典的李超线段树题。
就是处理细节比较多,要离线处理插入的线段,要对时间离散化。
代码
明明是道水题,我却调了2个多小时,因为一些奇奇怪怪的原因(如 \(double\) 和 \(longlong\) 啊,对时间离散化还是动态开点啊,线段的端点问题啊。。。)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int read(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch) && ch!='-') ch=getchar();
if(ch=='-') f=-1,ch=getchar();
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int N = 600005;
typedef double db;
typedef long long ll;
struct seg{
int x0,x1;
ll k,b;
seg() { x0=x1=0; k=b=0.0; }
seg(int _x0,int _x1,ll _k,ll _b) { x0=_x0; x1=_x1; k=_k; b=_b; }
}d[N];
int tot;
int ask[N],num;
int n;
ll K[N],B[N];
int st[N];
int rk[N*2],rn;
struct node{
node *ch[2];
int mx,mn;
node() { mx=mn=0; ch[0]=ch[1]=NULL; }
}pool[N*4],*root;
int cnt;
void build(node *p,int l,int r){
if(l==r) return;
int mid=(l+r)>>1;
build(p->ch[0]=&pool[++cnt],l,mid);
build(p->ch[1]=&pool[++cnt],mid+1,r);
}
inline ll cal(int x,int c) { return d[x].k*rk[c]+d[x].b; }
bool better_mn(int x,int y,int c) {
if(!x) return false;
if(!y) return true;
return cal(x,c)<cal(y,c);
}
bool better_mx(int x,int y,int c) {
if(!x) return false;
if(!y) return true;
return cal(x,c)>cal(y,c);
}
void insert_mx(node *p,int l,int r,int L,int R,int c){
if(l==L && r==R){
int mid=(l+r)>>1;
if(better_mx(c,p->mx,mid)) swap(p->mx,c);
int tl=better_mx(p->mx,c,l),tr=better_mx(p->mx,c,r);
if(c==0 || l==r || (tl && tr)) return;
if(tl) insert_mx(p->ch[1],mid+1,r,mid+1,r,c);
else insert_mx(p->ch[0],l,mid,l,mid,c);
return;
}
int mid=(l+r)>>1;
if(R<=mid) insert_mx(p->ch[0],l,mid,L,R,c);
else if(L>mid) insert_mx(p->ch[1],mid+1,r,L,R,c);
else{
insert_mx(p->ch[0],l,mid,L,mid,c);
insert_mx(p->ch[1],mid+1,r,mid+1,R,c);
}
}
void insert_mn(node *p,int l,int r,int L,int R,int c){
if(l==L && r==R){
int mid=(l+r)>>1;
if(better_mn(c,p->mn,mid)) swap(p->mn,c);
int tl=better_mn(p->mn,c,l),tr=better_mn(p->mn,c,r);
if(c==0 || l==r || (tl && tr)) return;
if(tl) insert_mn(p->ch[1],mid+1,r,mid+1,r,c);
else insert_mn(p->ch[0],l,mid,l,mid,c);
return;
}
int mid=(l+r)>>1;
if(R<=mid) insert_mn(p->ch[0],l,mid,L,R,c);
else if(L>mid) insert_mn(p->ch[1],mid+1,r,L,R,c);
else{
insert_mn(p->ch[0],l,mid,L,mid,c);
insert_mn(p->ch[1],mid+1,r,mid+1,R,c);
}
}
int Mx,Mn;
void query(node *p,int l,int r,int c){
Mx = better_mx(p->mx,Mx,c) ? p->mx : Mx ;
Mn = better_mn(p->mn,Mn,c) ? p->mn : Mn ;
if(l==r) return;
int mid=(l+r)>>1;
if(c<=mid) query(p->ch[0],l,mid,c);
else query(p->ch[1],mid+1,r,c);
}
int main()
{
int m,t,id,x;
char s[10];
n=read(); m=read();
for(int i=1;i<=n;i++)
K[i]=0,B[i]=read(),st[i]=1;
while(m--){
t=read()+1;
rk[++rn]=t;
scanf("%s",s);
if(s[0]=='c'){
id=read(); x=read();
d[++tot]=seg(st[id],t,K[id],B[id]);
st[id]=t;
B[id]=K[id]*t+B[id]-1ll*x*t;
K[id]=x;
}
else ask[num++]=t;
}
for(int i=1;i<=n;i++) d[++tot]=seg(st[i],t,K[i],B[i]);
rk[++rn]=1;
sort(rk+1,rk+1+rn);
rn=unique(rk+1,rk+1+rn)-rk-1;
build(root=&pool[++cnt],1,rn);
for(int i=1;i<=tot;i++){
if(d[i].x0==d[i].x1 && t!=1) continue;
d[i].x0=lower_bound(rk+1,rk+1+rn,d[i].x0)-rk;
d[i].x1=lower_bound(rk+1,rk+1+rn,d[i].x1)-rk;
insert_mx(root,1,rn,d[i].x0,d[i].x1,i);
insert_mn(root,1,rn,d[i].x0,d[i].x1,i);
}
for(int i=0;i<num;i++){
Mx=Mn=0;
ask[i]=lower_bound(rk+1,rk+1+rn,ask[i])-rk;
query(root,1,rn,ask[i]);
printf("%lld\n",max(abs(cal(Mx,ask[i])),abs(cal(Mn,ask[i]))));
}
return 0;
}
[bzoj3938] [Uoj #88] Robot的更多相关文章
- BZOJ3938 & UOJ88:[集训队互测2015]Robot——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3938 http://uoj.ac/problem/88 小q有n只机器人,一开始他把机器人放在了一 ...
- 【bzoj3938】 Robot
http://www.lydsy.com/JudgeOnline/problem.php?id=3938 (题目链接) 题意 给出数轴上$n$个点,有$m$个操作,在时间$t$让一个点以一定的速度移动 ...
- bzoj3938 Robot
3938: Robot Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 336 Solved: 112[Submit][Status][Discuss ...
- bzoj千题计划220:bzoj3938: Robot
http://www.lydsy.com/JudgeOnline/problem.php?id=3938 以时间为x轴,以距离为y轴,那么每个机器人的行走路径就是一条折线 把折线分段加入线段树里,然后 ...
- BZOJ3938:Robot
浅谈标记永久化:https://www.cnblogs.com/AKMer/p/10137227.html 题目传送门:https://www.lydsy.com/JudgeOnline/proble ...
- metasploit渗透初探MR.robot(一)
看了MR.robot,有一种研究渗透技术的冲动, 网上也看了些教程,要从kali linux说起, 下载vmware 12,http://www.vmware.com/go/tryworkstatio ...
- Jenkins+Gitlab CE+Robot Framework持续集成
环境 Ubuntu 14.04.3 LTS Desktop 前提 1.在本地能执行测试脚本(pybot yourTestSuit.txt),本文不讲解如何学习使用RF框架 2.已有Gitlab环境,本 ...
- 【集训队互测2015】Robot
题目描述 http://uoj.ac/problem/88 题解 维护两颗线段树,维护最大值和最小值,因为每次只有单点查询,所以可以直接在区间插入线段就可以了. 注意卡常,不要写STL,用链表把同类修 ...
- 编写高质量代码:改善Java程序的151个建议(第6章:枚举和注解___建议88~92)
建议88:用枚举实现工厂方法模式更简洁 工厂方法模式(Factory Method Pattern)是" 创建对象的接口,让子类决定实例化哪一个类,并使一个类的实例化延迟到其它子类" ...
随机推荐
- 2018-6-29-PTA-6-2-多项式求值
title author date CreateTime categories PTA 6-2 多项式求值 lindexi 2018-06-29 15:24:28 +0800 2018-6-14 22 ...
- 理解Servlet
题记:框架横行,似乎已经忘记JavaWeb最基础Servlet是如何工作的,这也是为什么要写这篇文章. Servlet是Java语言应用到Web的扩展技术,是运行在Web应用服务器上的Java程序.与 ...
- Linux 内核热插拔事件产生
一个热插拔事件是一个从内核到用户空间的通知, 在系统配置中有事情已经改变. 无论何 时一个 kobject 被创建或销毁就产生它们. 这样事件被产生, 例如, 当一个数字摄像头 使用一个 USB 线缆 ...
- 2018-2-13-Visual-studio-C#-代码使用-NotNull
title author date CreateTime categories Visual studio C# 代码使用 NotNull lindexi 2018-2-13 17:23:3 +080 ...
- 游戏《Minecraft》或其他应用程序 实现 自动更新 客户端版本
本渣又来写(水)博客了. 先说一下,我这个解决方案的安全性并不是企业级的,咱们就是一群穷开服的Minecraft玩家. 如果你要投入到企业级应用(容易被黑客攻击的场景),请自己写,思路凑合看看.不然安 ...
- Spring MVC 模拟
在Spring MVC中,将一个普通的java类标注上Controller注解之后,再将类中的方法使用RequestMapping注解标注,那么这个普通的java类就够处理Web请求,示例代码如下: ...
- python 批量生成xml标记文件(连通域坐标分割)
#!/usr/bin/python # -*- coding=utf-8 -*- # author : Manuel # date: 2019-05-15 from xml.etree import ...
- 基于MIG IP核的DDR3控制器(二)
上一节中,记录到了ddr控制器的整体架构,在本节中,准备把ddr控制器的各个模块完善一下. 可以看到上一节中介绍了DDR控制器的整体架构,因为这几周事情多,又要课设什么的麻烦,今天抽点时间把这个记录完 ...
- Autofac总结
Autofac 介绍|术语 控制反转:IOC和DI IOC 调用者不再创建(不自己new)被调用者的实例,而是交给容器去创建(AutoFac就充当这里的容器),这就是控制反转 控制反转中引入的第三方对 ...
- Spark学习笔记(一)——基础概述
本篇笔记主要说一下Spark到底是个什么东西,了解一下它的基本组成部分,了解一下基本的概念,为之后的学习做铺垫.过于细节的东西并不深究.在实际的操作过程中,才能够更加深刻的理解其内涵. 1.什么是Sp ...