小q有n只機械人,一開始他把機械人放在了一條數軸上,第i只機械人在ai的位置上靜止,而自己站在原點。在這之後小q會執行一些操作,他想要命令乙個機械人向左或者向右移動x格。但是機械人似乎聽不清小q的命令,事實上它們會以每秒x格的速度勻速移動。看著自己的機械人越走越遠,小q很著急,他想知道當前離他(原點)最遠的機械人有多遠。具體的操作以及詢問見輸入格式。注意,不同的機械人之間互不影響,即不用考慮兩個機械人撞在了一起的情況。
共有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。(注:若同一時間發生多次操作,則按讀入順序依次執行)
對於每個query詢問,輸出一行,包含乙個整數表示正確的答案。c/c++輸入輸出longlong時請用%lld。由於本題資料量較大,建議不要使用cin/cout進行輸入輸出。
4 5-20 0 20 100
10 command 1 10
20 command 3 -10
30 query
40 command 1 -30
50 query
180280
第乙個命令執行時,各個機械人的位置為:−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
每個結點都設定乙個覆蓋標記,
如果從來沒有線段覆蓋過,在初次覆蓋的時候直接看一下標記即可
查詢的時候也可以通過判斷標記防止答案錯誤
注意在判斷交點在哪乙個區間的時候,不要忘了線段樹的區間是離散後的時間
if (x<=ti[mid])
啊啊啊啊啊。。。。寫了一下午+一晚上
一開始沒有想明白離散化
後來發現沒有看見是絕對值最大
**量超長180+
if (rreturn;
終於變成了wa
本來是想借鑑一下前輩的**,最後只能找不同了。。。
在處理的時候,我們新增乙個時刻0,方便計算直線的斜率和截距
插入線段時候,我們把每乙個機械人按照操作順序分成若干段分別插入
資料應該是保證時間是單調遞增的
這道題雖然是自己想出來的,但是調了好久。。。
#include
#include
#include
#include
#define ll long long
using
namespace
std;
const
int inf=1e9;
const
int n=600005;
struct node;
node t[n<<2];
int n,m,nn;
struct point;
point po[n];
ll ti[n],a[n],maxx,minn,nowk[n],nowb[n];
bool f1[n<<2],f2[n<<2];
void change_max(int bh,int l,int r,int l,int r,ll k,ll b)
ll z1=t[bh].mxa*ti[l]+t[bh].mxb; //原線段
ll z2=t[bh].mxa*ti[r]+t[bh].mxb;
ll z3=k*ti[l]+b;
ll z4=k*ti[r]+b;
if (z1>=z3&&z2>=z4) return;
if (z1<=z3&&z2<=z4)
double x=(double)(t[bh].mxb-b)/(k-t[bh].mxa);
if (x<=ti[mid]) //對比的是原時間
}else
}return;
}if (l<=mid) change_max(bh<<1,l,mid,l,r,k,b);
if (r>mid) change_max((bh<<1)+1,mid+1,r,l,r,k,b);
}void change_min(int bh,int l,int r,int l,int r,ll k,ll b)
ll z1=t[bh].mna*ti[l]+t[bh].mnb; //原線段
ll z2=t[bh].mna*ti[r]+t[bh].mnb;
ll z3=k*ti[l]+b;
ll z4=k*ti[r]+b;
if (z1<=z3&&z2<=z4) return;
if (z1>=z3&&z2>=z4)
double x=(double)(t[bh].mnb-b)/(k-t[bh].mna);
if (x<=ti[mid]) //對比的是原時間
}else
}return;
}if (l<=mid) change_min(bh<<1,l,mid,l,r,k,b);
if (r>mid) change_min((bh<<1)+1,mid+1,r,l,r,k,b);
}void ask(int bh,int l,int r,int pos)
int main()
else po[i].type=2;
}int num=m;
ti[++num]=0; //新增乙個初試時刻0
sort(ti+1,ti+1+num); //離散化時間
nn=unique(ti+1,ti+1+num)-ti-1;
for (int i=1;i<=m;i++) if (po[i].type==1)
for (int i=1;i<=n;i++)
for (int i=1;i<=m;i++) if (po[i].type==2)
return
0;}
BZOJ 3938 Robot(超哥線段樹)
題目大意 一條數軸上有n個機械人,對其進行m次操作。操作t i commond k i x i 1 k i n 表示ti時刻將第ki個機械人的速度變為正方向上xi格每秒 操作t i query則是詢問ti時刻離原點最遠的機械人到原點的距離 t1 t2 t3 tm,若同一時間發生多次操作,則按讀入順序...
bzoj3280 小R的煩惱
description 小r最近遇上了 煩,他的程式設計掛科了。於是他只好找程設老師求情。善良的程設老師答應不掛他,但是要求小r幫助他一起解決乙個難題。問題是這樣的,程設老師最近要進行一項 的實驗來證明p np,這個實驗一共持續n天,第i天需要a i 個研究生來給他搬磚。研究生畢竟也是人,所以僱傭研...
bzoj 3280 小R的煩惱
題意 n天,m個學校,k個醫院。每天需要a i 個人,這a i 個人工作後處於瀕死狀態,你可以選擇把瀕死狀態的人送去醫院,治好後還可以繼續工作。每個醫院i救治乙個人需要d i 天,費用q i 元。學校 i 中乙個人工作一天薪酬為p i 思路 時間為乙個天然序,第i天的決策為從健康的人中選擇a i 個...