2017 12 02普及組模擬 送快遞

2021-08-11 19:42:31 字數 4055 閱讀 5065

petya和vasya被聘為快遞員。在工作日期間,他們將提供包裹到線上的不同點。根據公司的內部規定,包裹的交付必須嚴格按照一定的順序進行。最初,petya處於座標s1的點,vasya位於座標s2的點,n個顧客所需訪問的順序位於點x1,x2,...,xn。

這些人預先同意他們誰將交付給哪些客戶,然後他們的行為如下。當第i個客戶端的包裹被交付時,兩個快遞員中的其中乙個負責去送第i+1個。此時不送快遞員的那個原地不動。即快遞是嚴格按照顧客順序乙個個在送的,乙個快遞員在送的時候,另乙個快遞員是不動的。

由於要相互溝通,這些傢伙有對講機。對講機的工作距離不是很遠,所以petya和vasya想在送快遞的時候,使得他們的最大距離盡可能低。幫助petya和vasya儘量減少他們之間的最大距離,遵守所有交貨規則。

第一行包含三個整數n,s1,s2(1≤n≤100000,0≤s1,s2≤10^9) - petya和vasya的送貨數量和起始位置。

第二行包含n個整數x1,x2,...,xn - 客戶座標(0≤xi≤10^9),以便交貨。

保證,在數字s1,s2,x1,...,xn中沒有兩個相等。

只有一行乙個正數,即最小可能的最大距離。

樣例輸入1

2 0 10

5 6樣例輸出1

樣例輸入2

3 2 1

3 4 5

樣例輸出2

樣例輸入3

1 4 5

2樣例輸出3

在第乙個測試案例中,快遞員之間的初始距離為10.這個值將是答案,例如,petya可以執行兩次交付,vasya將保持在起點。

在第二個測試用例中,您可以通過以下方式進行最佳的操作:vasya向第乙個客戶送貨,petya到第二個,最後,vasya將包提供給第三個客戶。按照這種交貨順序,快遞員之間的距離不會超過1。

在第三個測試用例中,只有兩種情況是可能的:如果單個包裝的交付由petya執行,則它們之間的最大距離為5 - 2 = 3.如果vasya將提供包裝,最大距離為4 - 2 = 2.後一種方法是最優的。

對於20%的資料,n<=25

對於40%的資料, n<=100

對於60%的資料, n<=2000

對於100%的資料,n<=100000

為了表示方便,設x−

1=s1

,x0=

s2如果用暴力做,就會生成下圖這樣一棵搜尋樹:

我們很容易發現,在第i層中,每個節點中必有i。

將i提取出來,再將重複的節點(反正每個節點中兩個數反過來都一樣)壓在一起,

可以得到下面這張圖:

從這張圖中,很容易得出結論:在第i層中,若i-1層有節點,必定會生成i-1的節點。

對於這一題,「最大距離盡可能低」,在乙個句子中,一旦最大、最小兩個詞一起出現,就要果斷二分(除非兩個是並列關係),這是我目前沒有見過例外的規律。

所以,先二分答案,然後判斷是否成立。

判斷是否成立時,我們考慮一層一層計算

如果第i-1層有節點k,那麼節點k就可以生成第i層的k節點和i-1節點

這意味著,若k在某一層(假設為j)被刪掉,那麼在以後j+1到n層就不會生成k。

還有之前已經得出的結論:在第i層中,若i-1層有節點,必定會生成i-1的節點。

在第i層,節點k必須滿足xk

∈[xi

−ans

,xi+

ans]

,不然就要被刪掉

所以我們可以枚舉行,在每一行刪掉不滿足這個條件的節點。若i-1行有節點,就試著加入i-1(若i-1不符合條件一樣要刪)。

若到第n層有節點,則這個答案是成立的。

為了更高效地刪除節點,我使用了平衡樹操作。

時間複雜度o(

lg109n

lgn)

#include 

#include

#include

#include

using

namespace

std;

int n;

int _s[100010];

int* s=_s+1;

set q;

inline

bool ok(int);

int main()

printf("%d\n",res);

return0;}

inline

bool ok(int len)

return

1;}

//注釋同上

#include

#include

#include

using

namespace

std;

struct node

d[100001];

int cnt,root;

inline

void zig(int x)

d[x].r=y;

d[y].fa=x;

}inline

void zag(int x)

d[x].l=y;

d[y].fa=x;

}inline

void splay(int x,int t)

else

if (d[z].l==y)

else

if (d[z].r==y)

}if (!t)

root=x;

}inline

void insert(int x,int val)

; root=1;

return;

}while (1)

;d[x].l=cnt;

splay(cnt,0);

break;}}

else

if (val>d[x].val)

;d[x].r=cnt;

splay(cnt,0);

break;}}

}}inline

int pred(int val)

return ret;

} inline

int succ(int val)

else

x=d[x].r;

}return ret;

}int n;

int _s[100010];

int* s=_s+1;

inline

bool ok(int);

int main()

printf("%d\n",res);

return0;}

inline

bool ok(int len)

if (x=succ(up))

if (low<=s[i-1] && s[i-1]<=up)

insert(root,s[i-1]);

if (root==0)

return

0; }

return

1;}

set用紅黑樹實現,在這題中,splay的刪除相對高效。

刪掉小於low的節點時,只需把最大的小於low的節點旋轉到根,留下根的右子樹。

刪掉大於up的節點時道理一樣

set操作很簡單但跑得慢,splay要手打但跑得快。

有某位大佬發明了列舉列的演算法,完美利用資料的隨機性,能過!!!主要是有了一些break。但最壞情況下時間複雜度o(

lg109n

2)。在隨機資料下,時間遠遠沒有這麼多。 zhj的**,判斷是否成立時明顯兩重迴圈,卻跑了360ms。

2017 12 02普及組模擬 送快遞

petya和vasya被聘為快遞員。在工作日期間,他們將提供包裹到線上的不同點。根據公司的內部規定,包裹的交付必須嚴格按照一定的順序進行。最初,petya處於座標s1的點,vasya位於座標s2的點,n個顧客所需訪問的順序位於點x1,x2,xn。這些人預先同意他們誰將交付給哪些客戶,然後他們的行為如...

2017 12 02 NOIP提高組 模擬賽A組

t1 3555 gdkoi2014模擬 樹的直徑 t2 3542 清華集訓2014 氣泡排序 t3 3486 noip2013模擬聯考10 道路改建 rebuild 樹直徑的乙個性質,兩棵樹合併,形成新的樹的直徑的兩個端點為原樹中的四個端點之二。可以用反證法證明。用此性質本題就變成了lca裸題了 i...

普及組模擬賽 家族

題目描述 在乙個與世隔絕的島嶼上,有乙個有趣的現象 同乙個家族的人家總是相鄰的 這裡的相鄰是指東南西北四個方向 不同的家族之間總會有河流或是山丘隔絕,但同乙個家族的人不一定有相同姓氏。現在給你島上的地圖,求出島上有多少個不同的家族。島上的地圖有n 行,每行有若干列,每個格仔中要麼是 空格表示大海,要...