【NOIP2016提高組day2】蚯蚓
阿新 • • 發佈:2018-05-21
AC AS orm max 可能 printf display OS 例如
蛐蛐國王知道這樣不是長久之計,因為蚯蚓不僅會越來越多,還會越來越長。蛐蛐國王決定求助於一位有著洪荒之力的神秘人物,但是救兵還需要 m 秒才能到來. . . . . . ( m 為非負整數)
蛐蛐國王希望知道這 m 秒內的戰況。 具體來說,他希望知道: ? m 秒內,每一秒被切斷的蚯蚓被切斷前的長度(有 m 個數): ? m 秒後,所有蚯蚓的長度(有 n + m 個數)。 蛐蛐國王當然知道怎麽做啦! 但是他想考考你. . . . . .
\(x:xp+q\)
\(y:(y+q)p=yp+qp\)
顯然\[xp+q>yp+qp\]
於是將xp放在yp前面
x(1-p),y(1-p)同理。
那麽我們開三個不上升隊列,
第一個記錄原來的蚯蚓,
第二個記錄乘以p的蚯蚓
第三個記錄乘以(1-p)的蚯蚓,
在記錄每條就要入隊列的時間,就可以求出增加的長度
每次比較三個隊列的隊首,取最大的值x的切。
將xp加入第二個隊列的隊尾
將x(1-p)加入第三個隊列的隊尾
(第二個第三個隊列保證單調,上面證明了)
題目
本題中,我們將用符號 LcJ 表示對 c 向下取整,例如: L3.0J = L3.1J = L3.9J = 3 。 蛐蛐國最近蚯蚓成災了!隔壁跳蚤國的跳蚤也拿蚯蚓們沒辦法,蛐蛐國王只好去 請神刀手來幫他們消滅蚯蚓。
蛐蛐國裏現在共有 n 只蚯蚓( n 為正整數)。 每只蚯蚓擁有長度,我們設第 i 只匠 蚓的長度為 ai ( i = 1, 2, . . . , n ),並保證所有的長度都是非負整數(即:可能存在長度為 0 的蚯蚓)。
每一秒,神刀手會在所有的蚯蚓中,準確地找到最長的那一只(如有多個則任選 一個)將其切成兩半。 神刀手切開蚯蚓的位置由常數 p (是滿足 0 < p < 1 的有理數) 決定,設這只蚯蚓長度為 x ,神刀手會將其切成兩只長度分別為 LpxJ 和 x ? LpxJ 的匠 蚓。特殊地,如果這兩個數的其中一個等於 0 ,則這個長度為 0 的蚯蚓也會被保留。此 外,除了剛剛產生的兩只新蚯蚓,其余蚯蚓的長度都會增加q(是一個非負整常數)。
蛐蛐國王希望知道這 m 秒內的戰況。 具體來說,他希望知道: ? m 秒內,每一秒被切斷的蚯蚓被切斷前的長度(有 m 個數): ? m 秒後,所有蚯蚓的長度(有 n + m 個數)。 蛐蛐國王當然知道怎麽做啦! 但是他想考考你. . . . . .
分析
這題很坑爹,
假設有兩個數x、y,先後被切(x>y),那麽
分別分成xp,x(1-p),yp,y(1-p)。
那麽會先切那條呢?
發現,因為增長的速度一樣,所以就只比較切完y之後。
\(y:(y+q)p=yp+qp\)
顯然\[xp+q>yp+qp\]
於是將xp放在yp前面
x(1-p),y(1-p)同理。
那麽我們開三個不上升隊列,
第一個記錄原來的蚯蚓,
第二個記錄乘以p的蚯蚓
第三個記錄乘以(1-p)的蚯蚓,
在記錄每條就要入隊列的時間,就可以求出增加的長度
每次比較三個隊列的隊首,取最大的值x的切。
將xp加入第二個隊列的隊尾
將x(1-p)加入第三個隊列的隊尾
(第二個第三個隊列保證單調,上面證明了)
#include <cmath> #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> const int maxlongint=2147483647; const int mo=1000000007; const int N=7100005; using namespace std; struct ddx { int v,t; }d[3][N]; int s[3],t[3],n,m,tt,q,v,u; bool cmp(ddx x,ddx y) { return x.v>y.v; } int get(int i,int x) { if(s[i]>t[i]) return -maxlongint; return d[i][s[i]].v+q*(x-d[i][s[i]].t-1); } int compete(int x) { int pos=0; for(int i=0;i<=2;i++) { if(s[i]<=t[i]) if(get(i,x)>get(pos,x)) pos=i; } return pos; } int main() { freopen("earthworm.in","r",stdin); freopen("earthworm.out","w",stdout); scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&tt); for(int i=1;i<=n;i++) scanf("%d",&d[0][i].v); sort(d[0]+1,d[0]+1+n,cmp); s[0]=s[1]=s[2]=1; t[0]=n; for(int i=1;i<=m;i++) { int pos=compete(i),val=get(pos,i); if(i%tt==0) printf("%d ",val); s[pos]++; d[1][++t[1]].v=int(u*1.0/v*val); d[2][++t[2]].v=val-int(u*1.0/v*val); d[1][t[1]].t=i; d[2][t[2]].t=i; } cout<<endl; for(int i=1;i<=n+m;i++) { int pos=compete(m+1),val=get(pos,m+1); if(i%tt==0) printf("%d ",val); s[pos]++; } }
【NOIP2016提高組day2】蚯蚓