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. 3星|《十大全球CEO亲授企业高速成长的关键战略》:作为CEO,我也非常坦率地表明过家庭优先于工作

    十大全球CEO亲授 企业高速成长的关键战略(<哈佛商业评论>增刊) <哈佛商业评论>上的10来篇文章合集.大部分都看过,除了一篇中信的访谈,其他大部分是美国的有点旧的案例. 总 ...

  2. JAVA学习笔记--简介几个常见关键字static、final、this、super

    一.static static(静态的),可以放在类.方法.字段之前. 通常,当创建类时,就是在描述那个类的外观与行为.除非用 new 创建那个类的对象,否则,实际上并未获得任何对象.执行 new 来 ...

  3. org.apache.poi版本问题

    问题描述: 今天跑一段历史代码,发现不能启动,抛出java.lang.NoSuchFieldError: RETURN_NULL_AND_BLANK 问题 解决办法: 把org.apache.poi的 ...

  4. 论文笔记:Visualizing and Understanding Convolutional Networks

    2014 ECCV 纽约大学 Matthew D. Zeiler, Rob Fergus 简单介绍(What) 提出了一种可视化的技巧,能够看到CNN中间层的特征功能和分类操作. 通过对这些可视化信息 ...

  5. Hyper-V虚拟机联网设置

    转自:http://www.3lian.com/edu/2012/12-22/50492.html Windows 8中内置的Hyper-V管理器可以说给许多人带来了惊喜!在Hyper-V管理器强大的 ...

  6. centos上搭建git服务--4

    Git是目前世界上最先进的分布式版本控制系统(没有之一).使用Svn的请参考<版本控制-svn服务器搭建和常用命令(centos 6.3)>,下面介绍Git的常用命令 常用命令 简单版 升 ...

  7. AppCan 之初体验

    平台概述 什么是AppCan 移步这里,楼主的一句话:可以匹敌 Phonegap .Titanium .Sencha Touch .MUI .ImagApp.Nitrous .apicloud .起步 ...

  8. 蜗牛慢慢爬 LeetCode 3. Longest Substring Without Repeating Characters [Difficulty: Medium]

    题目 Given a string, find the length of the longest substring without repeating characters. Examples: ...

  9. vue-cli脚手架搭建

    我们使用vue-cli来搭建整个项目,vue-cli就是一个脚手架,步骤很简单,输入几个命令之后就会生成整个项目,里面包括了webpack.ESLint.babel很多配置等等,省了很多事 Vue+ ...

  10. web.py 笔记

    1.涉及到id=‘id’的情况,需要加入  vars=locals()  ,因为id在python里有id() 函数 db.delete('entries', where = 'id = $id', ...