1. 程式人生 > >BZOJ3938 & UOJ88:[集訓隊互測2015]Robot——題解

BZOJ3938 & UOJ88:[集訓隊互測2015]Robot——題解

esp 其他人 turn logs else ons uoj class ont

https://www.lydsy.com/JudgeOnline/problem.php?id=3938

http://uoj.ac/problem/88

小q有n只機器人,一開始他把機器人放在了一條數軸上,第i只機器人在ai的位置上靜止,而自己站在原點。在這之後小q會執行一些操作,他想要命令一個機器人向左或者向右移動x格。但是機器人似乎聽不清小q的命令,事實上它們會以每秒x格的速度勻速移動。看著自己的機器人越走越遠,小q很著急,他想知道當前離他(原點)最遠的機器人有多遠。具體的操作以及詢問見輸入格式。註意,不同的機器人之間互不影響,即不用考慮兩個機器人撞在了一起的情況。

顯然機器人的運動是一個分段一次函數,故可以李超線段樹維護之。

然而t很大,所以需要離散化,但是為了答案的正確性,我們需要存真的斜率和截距。

於是參考了其他人的代碼,加上自己的碼風,將原來的板子又推翻重建,變成了現在這個模樣,應該很好看。

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include
<iostream> #include<algorithm> using namespace std; typedef long long ll; typedef pair<int,int> pii; #define fi first #define se second const int N=1e5+10; const int M=5e5+10; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch==-;ch=getchar();}
while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } vector<pii>a[N]; int t[N+M],q[M],lim,n,m; char s[20]; struct node{ int l,r; ll k,b; node(int L=0,int R=0,ll K=0,ll B=0){ l=L,r=R,k=K,b=B; } ll point(int x){return k*x+b;} }mx[(N+M)*4],mn[(N+M)*4]; inline int LSH(int x){ return lower_bound(t+1,t+lim+1,x)-t; } ll query(int a,int l,int r,int k){ ll a1=abs(mx[a].point(t[k])),a2=abs(mn[a].point(t[k])); if(l==r)return max(a1,a2); int mid=(l+r)>>1;ll ans; if(k<=mid)ans=query(a<<1,l,mid,k); else ans=query(a<<1|1,mid+1,r,k); return max(ans,max(a1,a2)); } void upt(int a,int l,int r,node k){ int mid=(l+r)>>1; if(k.point(t[mid])>mx[a].point(t[mid]))swap(k,mx[a]); if(l==r)return; if(min(mx[a].point(t[l]),mx[a].point(t[r]))>=max(k.point(t[l]),k.point(t[r])))return; if(mx[a].k>k.k)upt(a<<1,l,mid,k); else upt(a<<1|1,mid+1,r,k); } void dwn(int a,int l,int r,node k){ int mid=(l+r)>>1; if(k.point(t[mid])<mn[a].point(t[mid]))swap(k,mn[a]); if(l==r)return; if(max(mn[a].point(t[l]),mn[a].point(t[r]))<=min(k.point(t[l]),k.point(t[r])))return; if(mn[a].k<=k.k)dwn(a<<1,l,mid,k); else dwn(a<<1|1,mid+1,r,k); } void insert(int a,int l,int r,node k){ if(r<k.l||k.r<l)return; if(k.l<=l&&r<=k.r){ upt(a,l,r,k);dwn(a,l,r,k); return; } if(l==r)return; int mid=(l+r)>>1; insert(a<<1,l,mid,k);insert(a<<1|1,mid+1,r,k); } int main(){ n=read(),m=read(); for(int i=1;i<=n;i++)a[i].push_back(pii(0,read())); t[++lim]=0; for(int i=1;i<=m;i++){ int x=read();t[++lim]=x;scanf("%s",s); if(s[0]==c){ int id=read(),v=read(); a[id].push_back(pii(x,v)); }else q[++q[0]]=x; } for(int i=1;i<=n;i++)a[i].push_back(pii(1e9,0)); t[++lim]=1e9; sort(t+1,t+lim+1); lim=unique(t+1,t+lim+1)-t; for(int i=1;i<=n;i++){ int sz=a[i].size(); ll now=a[i][0].se; node p=node(LSH(a[i][0].fi),LSH(a[i][1].fi),0,now); insert(1,1,lim,p); for(int j=1;j<sz-1;j++){ int l=a[i][j].fi,r=a[i][j+1].fi,k=a[i][j].se; p=node(LSH(l),LSH(r),k,now-(ll)k*l); insert(1,1,lim,p); now=now+(ll)k*(r-l); } } for(int i=1;i<=q[0];i++) printf("%lld\n",query(1,1,lim,LSH(q[i]))); return 0; }

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+歡迎訪問我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ3938 & UOJ88:[集訓隊互測2015]Robot——題解