time limit: 5 sec memory limit: 64 mb
submit: 1526 solved: 639
[submit][status][discuss]
第一行乙個整數n(1<=n<=1000000)。n表示士兵數,m表示總命令數。 第二行n個整數,其中第i個數表示編號為i的士兵的分數。(分數都是[0..10000]之間的整數) 第三行乙個整數m(1<=m<=100000) 第3+i行描述第i條命令。命令為如下兩種形式: 1. m i j 2. k i
如果命令是kill,對應的請輸出被殺人的分數。(如果這個人不存在,就輸出0)
5100 90 66 99 10
7m 1 5
k 1k 1
m 2 3
m 3 4
k 5k 4
10100066
斜堆模版題 然而出題人還要加個並查集...
然而我跑得特別慢...
國際慣例是不是應該扔點東西上來啊?
——————————————————
斜堆(skew heap)也叫自適應堆(self-adjusting heap),它是左傾堆的乙個變種。和左傾堆一樣,它通常也用於實現優先佇列;作為一種自適應的左傾堆,它的合併操作的時間複雜度也是o(lg n)。
斜堆的合併操作
(01) 如果乙個空斜堆與乙個非空斜堆合併,返回非空斜堆。
(02) 如果兩個斜堆都非空,那麼比較兩個根節點,取較小堆的根節點為新的根節點。將"較小堆的根節點的右孩子"和"較大堆"進行合併。
(03) 合併後,交換新堆根節點的左孩子和右孩子。
——————————————————
1 #include2view code#define rep(i,l,r) for(int i=l;i<=r;++i)
3using
namespace
std;
4const
int n=1023333;5
intn,q,v[n],l[n],r[n],x,y,f[n];
6bool
vis[n];
7char s[10];8
int find(int
x)11
int merge(int a,int
b)17
intmain()
32 }else
35 x=find(x);
36 printf("
%d\n
",v[x]);
37 vis[x]=1
;38 f[x]=merge(l[x],r[x]);
39 f[f[x]]=f[x];40}
41}42 }
bzoj 1455 羅馬遊戲
link 羅馬遊戲 這道題 每次合併兩個集合 或者 每次找到某個集合中值最小的並且將其刪掉。發現直接主席樹 主席樹合併即可 但是這樣做過於不優美且 n leq 1000000 這樣做在常數上不優秀。我們考慮開堆 合併兩個堆?啟發式合併?nlog 2崩掉。那直接開斜堆 即左偏樹 或者說可並堆。這樣合併...
bzoj1455羅馬遊戲
bzoj1455羅馬遊戲 題意 維護資料結構支援合併和彈出最小值。n 1000000,m 100000 題解 可並堆,注意本題合併時要判斷兩個節點是否在同乙個堆中。本弱寫了左偏樹和斜堆,發現斜堆比左偏樹快,不知道為什麼,求神犇解答。1 include 2 include 3 include 4 de...
BZOJ1455 羅馬遊戲 左偏樹
題解 本題顯然可以用堆來實現,維護乙個大根堆 但是無法進行合併操作,於是我們想到左偏樹。定義乙個結點的斜深度為這個節點不斷向自己的右兒子走 直到為葉子節點的長度。左偏樹的 左偏 指左兒子的斜深度一定大於等於右兒子的斜深度。合併就簡單了,我們可以歸併的來維護乙個左偏樹,設需合併的兩個樹的根節點為 k1...