3938: Robot

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 336  Solved: 112
[Submit][Status][Discuss]

Description

小q有n只机器人,一开始他把机器人放在了一条数轴上,第i只机器人在ai的位置上静止,而自己站在原点。在这
之后小q会执行一些操作,他想要命令一个机器人向左或者向右移动x格。但是机器人似乎听不清小q的命令,事实
上它们会以每秒x格的速度匀速移动。看着自己的机器人越走越远,小q很着急,他想知道当前离他(原点)最远的
机器人有多远。具体的操作以及询问见输入格式。注意,不同的机器人之间互不影响,即不用考虑两个机器人撞在
了一起的情况。
 
 

Input

共有m个事件,输入将会按事件的时间顺序给出。第一行两个正整数n,m。接下来一行n个整数,第i个数是ai,表示
第i个机器人初始的位置(初始移动速度为0)。接下来m行,每行行首是一个非负整数ti,表示该事件点发生的时
刻(以秒为单位)。第二个是一个字符串S,代表操作的种类。数字与字符串之间用一个空格隔开。接下来的输入
按S的种类分类。若S是“command”(不带引号),则接下来两个整数ki,xi,表示小q对第ki个机器人执行了操作
,该机器人的速度将会被重置,变为向数轴正方向每秒移动xi格(若xi为负数就相当于向数轴负方向每秒移动∣xi
∣格)。保证1≤ki≤n。若S是“query”(不带引号),则你需要输出当前离原点最远的机器人有多远。保证t1≤
t2≤t2≤...≤tm。(注:若同一时间发生多次操作,则按读入顺序依次执行)
 

Output

对于每个query询问,输出一行,包含一个整数表示正确的答案。C/C++输入输出longlong时请用%lld。由于本题数
据量较大,建议不要使用cin/cout进行输入输出。
 

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≤ti≤10^9,对于所有的 command 满足 ∣xi∣≤10^4。
对于所有的机器人满足 ∣ai∣≤10^9。
N,C<=10^5
Q<=5*10^5

Source

分析:这道题和bzoj1568差不多,将t看做横坐标,相对于原点的距离看做纵坐标,最后求最大值和最小值,取各自绝对值的最大值,无非就是把直线改成了一条条的折线段.折线段的处理比较麻烦,比较考验细节处理能力.转化完后做法就基本上是一样的了.
          一些细节地方在代码中有注释
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; typedef long long ll; const ll maxn = ; ll n,m;
ll Tim[maxn],v[maxn],d[maxn],cnt,Time[maxn],ans1,ans2;
bool vis1[maxn << ],vis2[maxn << ]; struct node
{
ll Time,V;
ll opt,pos;
} a[maxn]; struct node2
{
ll k,b;
ll id;
} e1[maxn << ],e2[maxn << ]; double jiao(node2 a,node2 b)
{
return (double)(a.b - b.b) / (b.k - a.k);
} bool cmp(node2 a,node2 b,ll pos)
{
return a.k * pos + a.b < b.k * pos + b.b;
} void update1(int o,int l,int r,int x,int y,node2 a)
{
int mid = (l + r) >> ;
if (x <= l && r <= y)
{
if (!vis1[o])
{
vis1[o] = ;
e1[o] = a;
}
else
{
ll l1 = a.b + a.k * Tim[l],l2 = a.b + a.k * Tim[r];
ll r1 = e1[o].b + e1[o].k * Tim[l],r2 = e1[o].b + e1[o].k * Tim[r];
if (l1 <= r1 && l2 <= r2)
return;
if (l1 >= r1 && l2 >= r2)
e1[o] = a;
else
{
double X = jiao(a,e1[o]);
if (l1 >= r1)
{
if (X <= Tim[mid])
update1(o * ,l,mid,x,y,a);
else
update1(o * + ,mid + ,r,x,y,e1[o]),e1[o] = a;
}
else
{
if (X > Tim[mid])
update1(o * + ,mid + ,r,x,y,a);
else
update1(o * ,l,mid,x,y,e1[o]),e1[o] = a;
}
}
}
return;
}
if (x <= mid)
update1(o * ,l,mid,x,y,a);
if (y > mid)
update1(o * + ,mid + ,r,x,y,a);
} void update2(int o,int l,int r,int x,int y,node2 a)
{
int mid = (l + r) >> ;
if (x <= l && r <= y)
{
if (!vis2[o])
{
vis2[o] = ;
e2[o] = a;
}
else
{
ll l1 = a.b + a.k * Tim[l],l2 = a.b + a.k * Tim[r];
ll r1 = e2[o].b + e2[o].k * Tim[l],r2 = e2[o].b + e2[o].k * Tim[r];
if (l1 >= r1 && l2 >= r2)
return;
if (l1 <= r1 && l2 <= r2)
e2[o] = a;
else
{
double X = jiao(a,e2[o]);
if (l1 <= r1)
{
if (X <= Tim[mid])
update2(o * ,l,mid,x,y,a);
else
update2(o * + ,mid + ,r,x,y,e2[o]),e2[o] = a;
}
else
{
if (X > Tim[mid])
update2(o * + ,mid + ,r,x,y,a);
else
update2(o * ,l,mid,x,y,e2[o]),e2[o] = a;
}
}
}
return;
}
if (x <= mid)
update2(o * ,l,mid,x,y,a);
if (y > mid)
update2(o * + ,mid + ,r,x,y,a);
} node2 query1(ll o,ll l,ll r,ll pos)
{
if (l == r)
return e1[o];
ll mid = (l + r) >> ;
node2 temp;
if (pos <= mid)
temp = query1(o * ,l,mid,pos);
else
temp = query1(o * + ,mid + ,r,pos);
if (cmp(temp,e1[o],Tim[pos]))
return e1[o];
else
return temp;
} node2 query2(ll o,ll l,ll r,ll pos)
{
if (l == r)
return e2[o];
ll mid = (l + r) >> ;
node2 temp;
if (pos <= mid)
temp = query2(o * ,l,mid,pos);
else
temp = query2(o * + ,mid + ,r,pos);
if (cmp(temp,e2[o],Tim[pos]))
return temp;
else
return e2[o];
} int main()
{
scanf("%lld%lld",&n,&m);
for (ll i = ; i <= n; i++)
scanf("%lld",&d[i]);
for (ll i = ; i <= m; i++)
{
scanf("%lld",&Tim[i]);
a[i].Time = Tim[i];
char ch[];
scanf("%s",ch);
if (ch[] == 'c')
{
a[i].opt = ;
scanf("%lld%lld",&a[i].pos,&a[i].V);
}
else
a[i].opt = ;
}
cnt = m + ;
Tim[cnt] = ; //为了插入初始线段,加一个Tim = 0
sort(Tim + ,Tim + + cnt);
cnt = unique(Tim + ,Tim + + cnt) - Tim - ; //去重离散化
for (ll i = ; i <= m; i++)
if (a[i].opt == )
{
ll pos = a[i].pos;
ll l = lower_bound(Tim + ,Tim + + cnt,Time[pos]) - Tim;
ll r = lower_bound(Tim + ,Tim + + cnt,a[i].Time) - Tim;
node2 temp;
temp.k = v[pos]; //线段的斜率和截距
temp.b = d[pos];
update1(,,cnt,l,r,temp);
update2(,,cnt,l,r,temp);
d[pos] += a[i].Time * (v[pos] - a[i].V); //新线段的截距.至于怎么求的,利用两条直线的交点列方程.a[i].Time就是交点横坐标
v[pos] = a[i].V; //v是记录上一次的斜率
Time[pos] = a[i].Time; //记录上一次这个机器人更改的时间
}
for (ll i = ; i <= n; i++)
{
ll l = lower_bound(Tim + ,Tim + + cnt,Time[i]) - Tim;
node2 temp;
temp.k = v[i];
temp.b = d[i];
update1(,,cnt,l,cnt,temp); //最后一条线段变成一条射线,延伸到右端点
update2(,,cnt,l,cnt,temp);
}
for (ll i = ; i <= m; i++)
if (a[i].opt == )
{
ll l = lower_bound(Tim + ,Tim + + cnt,a[i].Time) - Tim;
node2 temp1 = query1(,,cnt,l);
node2 temp2 = query2(,,cnt,l);
ll ans1 = temp1.k * Tim[l] + temp1.b;
ll ans2 = temp2.k * Tim[l] + temp2.b;
printf("%lld\n",max(ans1,-ans2));
} return ;
}

bzoj3938 Robot的更多相关文章

  1. bzoj千题计划220:bzoj3938: Robot

    http://www.lydsy.com/JudgeOnline/problem.php?id=3938 以时间为x轴,以距离为y轴,那么每个机器人的行走路径就是一条折线 把折线分段加入线段树里,然后 ...

  2. 【bzoj3938】 Robot

    http://www.lydsy.com/JudgeOnline/problem.php?id=3938 (题目链接) 题意 给出数轴上$n$个点,有$m$个操作,在时间$t$让一个点以一定的速度移动 ...

  3. BZOJ3938 & UOJ88:[集训队互测2015]Robot——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3938 http://uoj.ac/problem/88 小q有n只机器人,一开始他把机器人放在了一 ...

  4. BZOJ3938:Robot

    浅谈标记永久化:https://www.cnblogs.com/AKMer/p/10137227.html 题目传送门:https://www.lydsy.com/JudgeOnline/proble ...

  5. [bzoj3938] [Uoj #88] Robot

    Description 小 \(q\) 有 \(n\) 只机器人,一开始他把机器人放在了一条数轴上,第 \(i\) 只机器人在 \(a_i\) 的位置上静止,而自己站在原点.在这之后小 \(q\) 会 ...

  6. Robot Framework用户手册 (版本:3.0)

    版权信息:诺基亚网络和解决中心 本翻译尊重原协议,仅用于个人学习使用 1.开始: 1.1 介绍: Robot Framework是一个基于Python的,为终端测试和验收驱动开发(ATDD)的可扩展的 ...

  7. selenium webdriver 右键另存为下载文件(结合robot and autoIt)

    首先感谢Lakshay Sharma 大神的指导 最近一直在研究selenium webdriver右键菜单,发现selenium webdriver 无法操作浏览器右键菜单,如图 如果我想右键另存为 ...

  8. RIDE -- Robot Framework setup

    RobotFramework 是一款基于python 的可以实现关键字驱动和数据驱动并能够生成比较漂亮的测试报告的一款测试框架 这里使用的环境是 python-2.7.10.amd64.msi RID ...

  9. [8.2] Robot in a Grid

    Imagine a robot sitting on the upper left corner of grid with r rows and c columns. The robot can on ...

随机推荐

  1. ip route ifconfig 基本命令

    1.route命令 route –n route add –net 192.168.2.0/24 dev eth0 route add –net 192.168.2.0 netmask 255.255 ...

  2. Paper Reading - Sequence to Sequence Learning with Neural Networks ( NIPS 2014 )

    Link of the Paper: https://arxiv.org/pdf/1409.3215.pdf Main Points: Encoder-Decoder Model: Input seq ...

  3. 作业 20181030-3互评Alpha版本

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2323 组名:可以低头,但没必要 组长:付佳 组员:张俊余  李文涛  孙 ...

  4. 20172305 2018-2019-1 《Java软件结构与数据结构》第八周学习总结

    20172305 2018-2019-1 <Java软件结构与数据结构>第八周学习总结 教材学习内容总结 本周内容主要为书第十二章内容: 堆(附加属性的二叉树) 完全二叉树 (最小堆)对于 ...

  5. POJ 2376 (区间问题,贪心)

    题目链接:http://poj.org/problem?id=2376 题目大意:选择一些区间使得能够覆盖1-T中的每一个点,并且区间数最少 题目分析:这道题目很明显可以用贪心法来解决.但题目没有看起 ...

  6. Python学习 - 入门篇2(更新中)

    前言 学习渠道:慕课网:Python进阶 记录原因:我只是想边上课边做笔记而已,呵呵哒 食用提示:教程环境基于Python 2.x,有些内容在Python 3.x中已经改变 函数式编程 定义:一种抽象 ...

  7. CodeForces 154A Hometask dp

    题目链接: http://codeforces.com/problemset/problem/154/A 题意: 给你一个字符串,和若干模板串(长度为2),至少删除多少个字母,使得字符串的字串里面没有 ...

  8. 新手使用github过程记录

    初次接触github,记录下我的使用过程.一开始确实有些懵,但好在网上这类的教程有很多,过程也很详细易懂,按照网上的教程走完全没问题,感谢无私分享辛苦整理的各位前辈们. 注册github账号 创建一个 ...

  9. C#的lock语句

    文章:lock 语句(C# 参考) 代码: using System; using System.Threading.Tasks; public class Account { private rea ...

  10. Java中按值传递与按引用传递的区别

    值传递:(形式参数类型是基本数据类型):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数值的改变不影响 ...