BZOJ 3938 Robot
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坐标,那么就是一个一次函数
改变速度的处理可以离线,预处理出每一个一次函数所覆盖的区间
坐标太大需要离散
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 }