码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 3938 Robot

时间:2018-01-21 12:27:00      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:pen   out   lin   格式   char   desc   一个   坐标   ring   

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
把时间看做x坐标,距离看做y坐标,那么就是一个一次函数
改变速度的处理可以离线,预处理出每一个一次函数所覆盖的区间
坐标太大需要离散
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<vector>
  7 using namespace std;
  8 typedef long long lol;
  9 struct ZYYS
 10 {
 11   lol l,r,k,id,b;
 12 };
 13 struct rubbish
 14 {
 15   lol t,k,id;
 16   bool kind;
 17 }q[600001];
 18 struct caiji
 19 {
 20   int p,x;
 21 }b[600001];
 22 struct Line
 23 {
 24   lol k,b;
 25   bool id;
 26 }tree1[5000005],tree2[5000005];
 27 lol h[600005],nowb[500001],nowk[500001],a[500001];
 28 lol ansmax,ansmin,T;
 29 int n,m,num,size;
 30 char ch[40];
 31 lol gi()
 32 {
 33   lol x=0,flag=1;
 34   char c=getchar();
 35   while (c<0||c>9) 
 36   {
 37     if (c==-) flag=-1;
 38      c=getchar();
 39   }
 40   while (c>=0&&c<=9)
 41     {
 42       x=x*10+c-0;
 43       c=getchar();
 44     }
 45   return x*flag;
 46 }
 47 bool pd(Line a,Line b,lol x)
 48 {
 49   return a.k*x+a.b>b.k*x+b.b;
 50 }
 51 double cross(Line a,Line b)
 52 {
 53     return (a.b-b.b)/(1.0*(b.k-a.k));
 54 }
 55 lol cal(Line a,lol x)
 56 {
 57   return a.k*x+a.b;
 58 }
 59 void add_max(int rt,int l,int r,Line x)
 60 {
 61   if (l>r) return;
 62   if (!tree1[rt].id)
 63     {
 64      tree1[rt]=x;
 65     return;
 66     }
 67     lol f1=cal(x,h[l]);lol f2=cal(tree1[rt],h[l]);
 68     lol f3=cal(x,h[r]);lol f4=cal(tree1[rt],h[r]);
 69     if (f1<=f2&&f3<=f4) return;
 70     if (f1>=f2&&f3>=f4)
 71     {tree1[rt]=x;return;}
 72     int mid=(l+r)/2;
 73     double p=cross(tree1[rt],x);
 74     if (f1>=f2)
 75     {
 76         if (p<=h[mid]) add_max(rt<<1,l,mid,x);
 77         else add_max(rt<<1|1,mid+1,r,tree1[rt]),tree1[rt]=x;
 78     }
 79     else
 80     {
 81         if (p>h[mid]) add_max(rt<<1|1,mid+1,r,x);
 82         else add_max(rt<<1,l,mid,tree1[rt]),tree1[rt]=x;
 83     }
 84 }
 85 void add_min(int rt,int l,int r,Line x)
 86 {
 87   if (l>r) return;
 88   if (!tree2[rt].id)
 89     {
 90      tree2[rt]=x;
 91      return;
 92     }
 93     lol f1=cal(x,h[l]);lol f2=cal(tree2[rt],h[l]);
 94     lol f3=cal(x,h[r]);lol f4=cal(tree2[rt],h[r]);
 95     if (f1>=f2&&f3>=f4) return;
 96     if (f1<=f2&&f3<=f4)
 97     {tree2[rt]=x;return;}
 98     int mid=(l+r)/2;
 99     double p=cross(tree2[rt],x);
100     if (f1<=f2)
101     {
102         if (p<=h[mid]) add_min(rt<<1,l,mid,x);
103         else add_min(rt<<1|1,mid+1,r,tree2[rt]),tree2[rt]=x;
104     }
105     else
106     {
107         if (p>h[mid]) add_min(rt<<1|1,mid+1,r,x);
108         else add_min(rt<<1,l,mid,tree2[rt]),tree2[rt]=x;
109     }
110 }
111 void update_max(int rt,int l,int r,int L,int R,Line x)
112 {
113   if (L>R) return;
114   if (l>r) return;
115   if (l>=L&&r<=R)
116     {
117       add_max(rt,l,r,x);
118       return;
119     }
120   int mid=(l+r)/2;
121   if (L<=mid) update_max(rt<<1,l,mid,L,R,x);
122   if (R>mid) update_max(rt<<1|1,mid+1,r,L,R,x);
123 }
124 void update_min(int rt,int l,int r,int L,int R,Line x)
125 {
126   if (L>R) return;
127   if (l>r) return;
128   if (l>=L&&r<=R)
129     {
130       add_min(rt,l,r,x);
131       return;
132     }
133   int mid=(l+r)/2;
134   if (L<=mid) update_min(rt<<1,l,mid,L,R,x);
135   if (R>mid) update_min(rt<<1|1,mid+1,r,L,R,x);
136 }
137 void query_max(int rt,int l,int r,int x)
138 {
139   if (l>r) return;
140   if (tree1[rt].id) ansmax=max(ansmax,cal(tree1[rt],h[x]));
141   //cout<<ansmax<<endl;
142   if (l==r)
143     {
144       return ;
145     }
146   int mid=(l+r)/2;
147   if (x<=mid) query_max(rt<<1,l,mid,x);
148   else query_max(rt<<1|1,mid+1,r,x);
149   return ;
150 }
151 void query_min(int rt,int l,int r,int x)
152 {
153   if (l>r) return ;
154   if (tree2[rt].id)
155     ansmin=min(ansmin,cal(tree2[rt],h[x]));
156     //cout<<ansmin<<endl;
157   if (l==r)
158     {
159       return ;
160     }
161   int mid=(l+r)/2;
162   if (x<=mid) query_min(rt<<1,l,mid,x);
163   else query_min(rt<<1|1,mid+1,r,x);
164   return ;
165 }
166 int main()
167 {lol i,x,j,p;
168   lol k,pos;
169   //freopen("robot.in","r",stdin);
170   //freopen("robot.out","w",stdout);
171   n=gi();m=gi();
172     for (i=1;i<=n;i++)
173     {
174       nowb[i]=gi();a[i]=0;nowk[i]=0;
175     }
176     h[1]=0;
177     for (i=1;i<=m;i++)
178     {
179         q[i].t=gi();
180         h[i+1]=q[i].t;
181         scanf("%s",ch);
182         if (ch[0]==c)
183         {
184             q[i].id=gi();q[i].k=gi();
185             q[i].kind=1;
186         }
187     }
188     size=unique(h+1,h+m+2)-h-1;
189     for (i=1;i<=m;i++)
190     if (q[i].kind)
191     {
192         int x=q[i].id;
193         int lst=lower_bound(h+1,h+size+1,a[x])-h;
194         int now=lower_bound(h+1,h+size+1,q[i].t)-h;
195         update_max(1,1,size,lst,now,(Line){nowk[x],nowb[x],1});
196         update_min(1,1,size,lst,now,(Line){nowk[x],nowb[x],1});
197         //cout<<lst<<‘ ‘<<now<<‘ ‘<<nowk[x]<<‘ ‘<<nowb[x]<<endl;
198         nowb[x]=nowb[x]+q[i].t*(nowk[x]-q[i].k);
199         nowk[x]=q[i].k;a[x]=q[i].t;
200     }
201     for (i=1;i<=n;i++)
202     {
203         int lst=lower_bound(h+1,h+size+1,a[i])-h;
204         update_max(1,1,size,lst,size,(Line){nowk[i],nowb[i],1});
205         update_min(1,1,size,lst,size,(Line){nowk[i],nowb[i],1});
206         //cout<<lst<<‘ ‘<<size<<‘ ‘<<nowk[i]<<‘ ‘<<nowb[i]<<endl;
207     }
208     for (i=1;i<=m;i++)
209     if (q[i].kind==0)
210     {
211         ansmax=0;
212         ansmin=0;
213         int t=lower_bound(h+1,h+size+1,q[i].t)-h;
214         query_max(1,1,size,t);
215         query_min(1,1,size,t);
216         printf("%lld\n",max(ansmax,-ansmin));
217     }
218 }

 

BZOJ 3938 Robot

标签:pen   out   lin   格式   char   desc   一个   坐标   ring   

原文地址:https://www.cnblogs.com/Y-E-T-I/p/8323584.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!