題目大意:
給定乙個長度為n的序列a,試求出對於序列a的每乙個字首的終極數x,使得
最小,試求出終極數t(如若有多個終極數t,只需輸出最小的那個)
題解:
雖然看似很迷,其實就是每次插入後的中位數中排序後的中位數:
我們維護兩個堆來處理,乙個大根堆,乙個小根堆,當前每次加入乙個數,必須保證
小根堆的個數大於等於大根堆的個數,可以理解為——第一次加入數的時候肯定是放
到最小堆。
其次,我們還需保證小根堆裡的每個值必須大於等於大根堆當中的最大值,這樣就可以使得每次小根堆的堆頂必定是當前的中位數。
然後每次插入任意乙個堆中的數,就要維護,然後判斷2個堆的堆頂
堆頂/小 < 堆頂/大 這時候很明顯我們需要替換,然後替換後分別維護一下,維護後繼續判斷,直到滿足小根堆根大根堆的定義以及滿足小根堆的每個值都大於等於大根堆得最大值。
最後將記錄下來的中位數排序輸出最終的中位數,即終極數。
var
smbi:array [1..2,0..1000001] of longint;
b:array [0..1000001] of longint;
n,i,j,k1,k2,d1,d2,x:longint;
procedure
qsort
(l,r:longint);
var i,j,mid:longint;
begin
if l>=r then
exit;
i:=l; j:=r;
mid:=b[(l+r) div
2]; repeat
while b[i]do inc(i);
while b[j]>mid do dec(j);
if i<=j then
begin
b[0]:=b[i];
b[i]:=b[j];
b[j]:=b[0];
inc(i); dec(j);
end;
until i>j;
qsort(i,r);
qsort(l,j);
end;
procedure
down
(x,y:longint);
var t:longint;
begin
if y*2>smbi[x,0] then
exit;
if x=1
then
repeat
y:=y*2;
if y0] then
if smbi[x,y]1] then inc(y);
if smbi[x,y div
2]then
begin
t:=smbi[x,y];
smbi[x,y]:=smbi[x,y div
2]; smbi[x,y div
2]:=t;
endelse
break;
until y*2>smbi[x,0];
if x=2
then
repeat
y:=y*2;
if y0] then
if smbi[x,y]>smbi[x,y+1] then inc(y);
if smbi[x,y div
2]>smbi[x,y]
then
begin
t:=smbi[x,y];
smbi[x,y]:=smbi[x,y div
2]; smbi[x,y div
2]:=t;
enduntil y*2>smbi[x,0];
end;
procedure
up(x,y:longint);
var k,t:longint;
begin
if y=1
then
exit;
if x=1
then
repeat
if smbi[x,y]>smbi[x,y div
2] then
begin
t:=smbi[x,y];
smbi[x,y]:=smbi[x,y div
2]; smbi[x,y div
2]:=t;
endelse
break;
y:=y div
2; until y=1;
if x=2
then
repeat
if smbi[x,y]div
2] then
begin
t:=smbi[x,y];
smbi[x,y]:=smbi[x,y div
2]; smbi[x,y div
2]:=t;
endelse
break;
y:=y div
2; until y=1;
end;
procedure
check;
var i:longint;
begin
i:=smbi[2,1];
smbi[2,1]:=smbi[1,1];
smbi[1,1]:=i;
end;
begin
assign(input,'c.in');reset(input);
assign(output,'c.out'); rewrite(output);
readln(n);
smbi[1,0]:=0; smbi[2,0]:=0;
k1:=1; k2:=1; d1:=1; d2:=1;
for i:=1
to n do
begin
read(x);
if i mod
2<>0
then
begin
if smbi[2,0]then smbi[2,0]:=smbi[2,0]+1
else
begin smbi[2,0]:=smbi[2,0]+1; d1:=d1*2; k1:=k1+d1 end;
smbi[2,smbi[2,0]]:=x;
up(2,smbi[2,0]);
endelse
begin
if smbi[1,0]then smbi[1,0]:=smbi[1,0]+1
else
begin smbi[1,0]:=smbi[1,0]+1; d2:=d2*2; k2:=k2+d2 end;
smbi[1,smbi[1,0]]:=x;
up(1,smbi[1,0]);
end;
while smbi[2,1]1,1] do
begin
check;
down(2,1);
down(1,1);
end;
b[i]:=smbi[2,1];
end;
qsort(1,n);
writeln(b[n div
2]);
close(input); close(output);
end.
jzoj P1330 迎接儀式
給出乙個不和諧的佇列,用 j 替代 教 z 替代 主 而乙個 j 與 z 組成的序列則可以描述當前的佇列。為了讓教主看得盡量舒服,你必須調整佇列,使得 jz 子串盡量多。每次調整你可以交換任意位置上的兩個人,也就是序列中任意位置上的兩個字母。而因為教主馬上就來了,時間僅夠最多作k次調整 當然可以調整...
jzoj P1331 超級教主
lhx教主很能跳,跳需要消耗能量,每跳1公尺就會消耗1點能量。教主為了收集能量,來到了乙個神秘的地方,教主的正上方每100公尺處就有乙個能量球 也就是這些能量球位於海拔100,200,300 公尺處 每個能量球所能提供的能量是不同的,一共有n個能量球 也就是最後乙個能量球在n 100公尺處 教主為了...
jzoj P3796 議案決定
國王手下有m個大臣,他們有一天對國王要處理的n件事務進行投票。每個大臣可以對兩件事務贊成或反對,格式如下 x c x y c y表示這個大臣對事務x的態度為c x,對事務y的態度為c y。如果國王的決定和某個大臣的兩個意見都不同,那麼這個大臣就會離開國王。小c認為不能讓任何乙個大臣離開國王,否則國王...