【bzoj3938】【Robot】【线段树】
来源:互联网 发布:著名搞笑网络歌曲 编辑:程序博客网 时间:2024/06/13 23:03
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
-20 0 20 100
10 command 1 10
20 command 3 -10
30 query
40 command 1 -30
50 query
Sample Output
180
280
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
题解:
把时间当x轴,距离当y轴,那每次就相当于插入一条线段.
然后就是线段树维护一次函数的经典问题了.
因为是绝对值最大,所以要维护最大值和最小值
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#define N 100010#define M 600010#define inf 1000000000000000ll#define LL long longusing namespace std;int mx[M<<2],mn[M<<2],n,m,x,v,size,num,h[M];LL ans,maxx,minn;struct node{int k;LL b;}line[M<<2];struct Q{int kind,t,x;}q[M];struct L{int l,r,k,cnt;LL b;};char ch[10];vector<L>xu[N];int read(){ int x(0),f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f;}LL cal(node t,int x){ LL ans; //cout<<t.k<<' '<<t.b<<' '<<x<<endl; ans=(LL)t.k*x+t.b; //cout<<ans<<endl; return ans;}void query(int k,int l,int r,int x){ int mid=(l+r)>>1;//cout<<l<<' '<<r<<' '<<x<<' '<<mx[k]<<' '<<mn[k]<<endl; if (mx[k]) maxx=max(maxx,cal(line[mx[k]],x)); if (mn[k]) minn=min(minn,cal(line[mn[k]],x)); if (l==r) return; if (x<=h[mid]) query(k<<1,l,mid,x); else query(k<<1|1,mid+1,r,x);}void insmn(int k,int l,int r,int ll,int rr,int pos){ int mid=(l+r)>>1; if (ll<=h[l]&&h[r]<=rr){ if (!mn[k]){mn[k]=pos;return;} node l1=line[mn[k]],l2=line[pos]; LL a1=cal(l1,h[l]),b1=cal(l1,h[r]); LL a2=cal(l2,h[l]),b2=cal(l2,h[r]); if (a1<=a2&&b1<=b2) return; if (a1>a2&&b1>b2){mn[k]=pos;return;} LL mid1=cal(l1,h[mid]),mid2=cal(l2,h[mid]); if (a1<=a2){ if (mid1>=mid2){ insmn(k<<1,l,mid,ll,rr,mn[k]); mn[k]=pos; } else insmn(k<<1|1,mid+1,r,ll,rr,pos); } else{ if (mid1>=mid2){ insmn(k<<1|1,mid+1,r,ll,rr,mn[k]); mn[k]=pos; } else insmn(k<<1,l,mid,ll,rr,pos); } } else{ if (ll<=h[mid]) insmn(k<<1,l,mid,ll,rr,pos); if (h[mid]<rr) insmn(k<<1|1,mid+1,r,ll,rr,pos); } }void insmx(int k,int l,int r,int ll,int rr,int pos){ int mid=(l+r)>>1; if (ll<=h[l]&&h[r]<=rr){ if (!mx[k]){mx[k]=pos;return;} node l1=line[mx[k]],l2=line[pos]; LL a1=cal(l1,h[l]),b1=cal(l1,h[r]); LL a2=cal(l2,h[l]),b2=cal(l2,h[r]); if (a1>=a2&&b1>=b2) return; if (a1<a2&&b1<b2){mx[k]=pos;return;} LL mid1=cal(l1,h[mid]),mid2=cal(l2,h[mid]); if (a1<=a2){ if (mid1<=mid2){ insmx(k<<1|1,mid+1,r,ll,rr,mx[k]); mx[k]=pos; } else insmx(k<<1,l,mid,ll,rr,pos); } else{ if (mid1<=mid2){ insmx(k<<1,l,mid,ll,rr,mx[k]); mx[k]=pos; } else insmx(k<<1|1,mid+1,r,ll,rr,pos); } } else{ if (ll<=h[mid]) insmx(k<<1,l,mid,ll,rr,pos); if (h[mid]<rr) insmx(k<<1|1,mid+1,r,ll,rr,pos); }}LL myabs(LL x){ if (x<0) return -x; else return x;}int main(){ //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); n=read();m=read();h[1]=0; for (int i=1;i<=n;i++){ x=read(); xu[i].push_back(L{0,0,0,++num,(LL)x}); } for (int i=1;i<=m;i++){ q[i].t=h[i+1]=read();scanf("%s",ch); if (ch[0]=='c'){ q[i].kind=1; x=read();v=read(); int temp=xu[x].size()-1; xu[x][temp].r=q[i].t; L now; now.l=q[i].t;now.r=0;now.k=v;now.cnt=++num; now.b=cal(node{xu[x][temp].k,xu[x][temp].b},q[i].t)-(LL)v*q[i].t; xu[x].push_back(now); } } for (int i=1;i<=n;i++) if (xu[i][xu[i].size()-1].r==0) xu[i][xu[i].size()-1].r=q[m].t; size=unique(h+1,h+m+2)-h-1; for (int i=1;i<=n;i++) for (int j=0;j<=xu[i].size()-1;j++){ L now=xu[i][j]; line[now.cnt]=node{now.k,now.b}; //cout<<now.k<<' '<<now.b<<' '<<now.l<<' '<<now.r<<endl; insmn(1,1,size,now.l,now.r,now.cnt); insmx(1,1,size,now.l,now.r,now.cnt); } // cout<<"-----"<<endl; for (int i=1;i<=m;i++) if (!q[i].kind){ maxx=-inf;minn=inf; query(1,1,size,q[i].t); //cout<<maxx<<' '<<minn<<endl; ans=max(myabs(maxx),myabs(minn)); printf("%lld\n",ans); }}
0 0
- 【bzoj3938】【Robot】【线段树】
- 【bzoj3938】Robot 超哥线段树
- BZOJ 3938 Robot 线段树
- 【bzoj 3938】Robot(超哥线段树)
- Robot
- robot
- robot
- Robot
- Robot
- 线段树?线段树!
- 线段树?线段树!
- 线段_线段树
- 线段_线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 利用synchronized关键字解决线程安全问题
- TCP连接诊断
- Tkinter教程之Button篇
- Android Studio gradle的配置与介绍
- artTemplate--使用artTemplate时,由于json对象属性有数字命名格式 导致调用报错 syntax error
- 【bzoj3938】【Robot】【线段树】
- java对日期Date类进行加减运算、年份加减,月份加减
- spark源码解析1
- cocoscreator:websocket集成使用protobuf
- MySQL入门知识_实验楼
- Qt Quick简介
- 随记
- 遇见C++ Lambda
- 线程基本知识和继承Thread类