首先考慮暴力:
每次都是拿最長的蚯蚓,容易想到用堆。
每次除拿出來的以外所有的蚯蚓都增長,容易想到用乙個懶惰標記來記錄所有的蚯蚓增長了多少。取最大的元素出來後加上標記的值,放元素進去的時候減去標記的值。
這時已經可以騙到60分了。
假設某一次取出來的元素長度為x,當前標記的值為inc,切完以後放進去的就是(x+inc)p-(inc+q)、(x+inc)(1-p)-(inc+q)兩個元素
由於(x+inc)p-(inc+q)-x=(x+inc)p-(x+inc)-q=(p-1)(x+inc)-q<0
(x+inc)(1-p)-(inc+q)-x=(x+inc)(1-p)-(x+inc)-q=-p(x+inc)-q<0
可知放進去的兩個元素必定都小於剛取出來的元素,也就是每次放進去的兩個元素依次遞減。
因此可以開三個佇列,第乙個佇列存放降序排序後的初始值,剩餘兩個佇列分別存放每次切出來的兩個元素。可以保證這三個佇列都是單調遞減的。每次比較三個佇列的頭元素,取最大的。
因為stl自帶佇列在不開優化的noip裡比較慢,所以最好手寫佇列。
#include #include#include
#include
#include
template
struct
myqueue
; //
頭尾指標
int size = 0
;
void
push(t val)
void
pop()
t front()
bool
empty()
};#define maxn 100005
using
namespace
std;
intn, m, q, t;
long
double p, eps = 1e-6
;myqueue
x, y, z;
int increase = 0
;int
pop_max()
if (!y.empty() && y.front() + increase >ew)
if (!z.empty() && z.front() + increase >ew)
switch (from
)
return
ew;}
inttmp[maxn];
intmain()
cout
cout
}
NOIP2016提高組 蚯蚓
搬來的。題目大意 每一輪有若干個正整數,每一輪會選出最大的乙個 設其為 x 並將 x 用兩個數取代之,乙個是 x p 乙個是x x p 其中 p 為乙個取值範圍為 0,1 的實數,而其餘的數都會加上乙個非負整數 q。一開始有 n 個數,要進行 m 輪操作,問每輪操 作刪掉的數和最後剩下的數。f1 n...
NOIp2016提高組 蚯蚓
題目大意 給你n個不同長度蚯蚓,每秒從裡面取出最長的砍下u v變成兩隻,又把剩下的加長q。問你在m之前的t,2t,3t.的時間上,砍的蚯蚓長度,以及m秒後剩下所有的蚯蚓長度。思路 很容易想到用乙個堆來解決,然而這樣時間複雜度是o m n log m n 的,過不去。所以複雜度得是線性的。考慮把原來的...
Noip 2016 提高組第二試 蚯蚓
蛐蛐國裡現在共有n只蚯蚓 n為正整數 每只蚯蚓擁有長度,我們設第i只蚯蚓的長度為a i i 1,2,n 並保證所有的長度都是非負整數 即 可能存在長度為0的蚯蚓 每一秒,神刀手會在所有的蚯蚓中,準確地找到最長的那乙隻將其切成兩半。神刀手切開蚯蚓的位置由常數p決定,設這只蚯蚓長度為x,神刀手會將其切成...