洛谷P3721 單旋

2022-04-30 11:00:10 字數 3659 閱讀 2656

什麼毒瘤......

題意:模擬一棵單旋splay,求每次插入,splay最值,刪除最值的操作次數。

解:乍一看感覺很神,又因為是lct題單上的,然後就折磨了我好久,最後跑去看題解...

居然是手玩找規律題!我瘋了。

是這樣的,因為它只會單旋,而且只會splay最值,手玩一下就發現整個樹的形態不變......就是把乙個節點拿上去當根了,然後它的子節點代替它的位置。

插入,根據普通splay插入可知它一定接在前驅/後繼的下面。找到深度大的那個就行了。

具體來說,用一棵值域線段樹維護每個權值的深度。同時還要記錄根,fa,son,樹中節點數...

線段樹要支援區間加,單點修改,查詢第k大,區間求和,單點查詢等功能。

大力分類討論,注意一波細節,然後就a了...

1 #include 2 #include 3

4const

int n = 100010;5

6struct

node node[n];910

int tag[n * 4], sum[n * 4], fa[n], s[n][2

], x[n], temp;

1112 inline void pushdown(int

o) 18

return;19

}2021int ask(int p, int l, int r, int

o) 26

return

tag[o];27}

28pushdown(o);

29int mid = (l + r) >> 1;30

if(p <=mid)

33else36}

3738

void change(int p, int v, int l, int r, int

o) 43

else

47return;48

}49pushdown(o);

50int mid = (l + r) >> 1;51

if(p <=mid)

54else

57 sum[o] = sum[o << 1] + sum[o << 1 | 1

];58

return;59

}6061int getk(int k, int l, int r, int

o) 65

int mid = (l + r) >> 1;66

if(k <= sum[o << 1

]) 69

else72}

7374

int getsum(int l, int r, int l, int r, int

o) 78

int mid = (l + r) >> 1, ans = 0;79

if(l <=mid)

82if(mid

85return

ans;86}

8788

void add(int l, int r, int v, int l, int r, int

o) 93

pushdown(o);

94int mid = (l + r) >> 1;95

if(l <=mid)

98if(mid

101return

;102

}103

104int

main()

113}

114 std::sort(x + 1, x + temp + 1

);115 temp = std::unique(x + 1, x + temp + 1) - x - 1

;116

for(int i = 1; i <= q; i++)

125else

if(!k)

131else

if(k ==siz)

137else

147else

152}

153 change(x, d, 1, temp, 1

);154 printf("

%d\n

", d);

155 siz++;

156}

157else

if(f == 2)

165 s[r][0] = s[x][1

];166 add(r, temp, 1, 1, temp, 1

);167 change(x, 1, 1, temp, 1

);168 fa[x] = 0

;169 s[x][1] =rt;

170 fa[rt] =x;

171 rt =x;

172}

173 printf("

%d\n

", d);

174}

175else

if(f == 3

) 183 s[l][1] = s[x][0

];184 add(1, l, 1, 1, temp, 1

);185 change(x, 1, 1, temp, 1

);186 fa[x] = 0

;187 s[x][0] =rt;

188 fa[rt] =x;

189 rt =x;

190}

191 printf("

%d\n

", d);

192}

193else

if(f == 4

) 201 s[r][0] = s[x][1

];202 add(1, r - 1, -1, 1, temp, 1

);203

}204

else

209 change(x, -1, 1, temp, 1

);210 printf("

%d\n

", d);

211 siz--;

212}

213else

if(f == 5

) 221 s[l][1] = s[x][0

];222 add(l + 1, temp, -1, 1, temp, 1

);223

}224

else

229 change(x, -1, 1, temp, 1

);230 printf("

%d\n

", d);

231 siz--;

232}

233}

234return0;

235 }

ac**

洛谷P5049 洛谷P5022 題解 旅行

原題 資料加強版 加強版 參考你谷題解 終於調過了 又是一如既往的申必錯誤 noi plus石錘了 原題的資料允許我們 o n 2 暴力斷邊,但是加強版的資料達到了 n log n 級別,我們必須在斷邊這一環節尋求更好的解法。考慮我們進入環後在何處回溯 根據繼續走環走到的點分類 設當前已經從 b 走...

洛谷 P3371 模板 單源最短路徑

題目大意 在乙個有向圖中,有m條邊 1 m 500000 n個點 1 n 10000 求點s到1 n個點的最短路徑長度,無最短路就輸出maxlongint。spfa 佇列優化 dis i 表示點s到i的最短路徑,一開始dis陣列為maxlongint。1.用佇列優化,就可以省略列舉每個點的時間,由o...

洛谷P3371 模板 單源最短路徑

p3371 模板 單源最短路徑 看了b站上的spfa演算法講解,重新敲了一遍這個題,學習spfa演算法。題意 給出乙個有向圖,請輸出從某一點出發到所有點的最短路徑長度。spfa演算法是對bellman ford演算法的優化。後者複雜度為o nm 每一輪都對所有邊確定是否更新。前者將點加入佇列中,用b...