集訓隊作業2018 樹(點分治 K短路)

2021-09-08 20:33:50 字數 2624 閱讀 2769

題解:

最近學數分學到意識模糊,做到oi題冷靜一下。

聯通塊強制選根,然後用dfs序轉化為乙個路徑然後就是做k短路了。

用點分治即可在圖大小為o(n

log⁡n)

o(n \log n)

o(nlogn)

的圖上做k短路,時間複雜度o(n

log⁡2n

+k

log⁡k)

o(n \log ^2 n + k\log k)

o(nlog2n

+klogk)。

#include

using

namespace std;

typedef

long

long ll;

typedef pair <

int,

int> pii;

typedef pair int> pli;

const

int rlen=

1<<18|

1;inline

charnc(

)inline

intrd()

while

(isdigit

(ch)

)return i*f;

}const

int n=

1e5+50;

int n,k,a[n]

,g;vector <

int> edge[n]

;int vis[n]

,dep[n]

,fa[n]

,sze[n]

,mx,total;

inline

void

calcg

(int x,

int f)

mx_son=

max(mx_son,total-sze[x]);

if(mx>mx_son) g=x, mx=mx_son;

}inline

void

dfs(

int x,

int f)

inline

void

solve

(int x,

int f)

}namespace ksp

struct node

*rt[n]

,pool[m]

,*pool=pool;

inline node*

newnode

(pli v=

pli(0,

0))struct data

friend

inline

bool

operator

<

(const data &a,

const data &b)};

inline node*

merge

(node *x,node *y)

inline

void

getdis()

int exi[n]

;inline

void

dfs2

(int x)

inline

void

solve()

k--;for

(int i=

1;i<=tot;i++

)dfs2

(i);

priority_queue q;

q.push

(data

(rt[2]

,0))

;while

(k)if

(u->lc) q.

push

(data

(u->lc,base));

if(u-

>rc) q.

push

(data

(u->rc,base));

if(rt[u-

>val.second]

) q.

push

(data

(rt[u-

>val.second]

,base+u-

>val.first));

}}}using ksp::add;

using ksp::tot;

int dfn[n]

,ord[n]

,ind;

inline

void

pre(

int x,

int lim,

int f=0)

inline

void

build

(int x)

tot+

=ind;

}int

main()

for(

int i=

1;i<=n;i++

) a[i]=rd

();

mx=total=n;

calcg(1

,0);

solve

(g,0);

for(

int i=

1;i<=n;i++

)build

(i);

ksp::

solve()

;}

集訓隊作業2018 喂鴿子

設 f n 表示有 n 只鴿子,每次等概率選乙隻喂,期望餵飽第一只鴿子的時間,f 表示有 n 只鴿子,已經喂了 m 次,此時這 n 只鴿子中沒有鴿子被餵飽的概率。ans sum n 1 f i f n sum sum f frac sum f sum frac 注意到有 dfrac n sum x ...

集訓隊作業2018 小Z的禮物

小水題。題意就是不斷隨機放乙個 1 times 2 骨牌,然後取走裡面的東西。求期望多少次取走所有的東西。然後有一維很小。首先顯然 minmax 容斥,將最後取走轉化為欽定一些物品,求第乙個取走的期望。然後顯然第乙個取走的期望只和剩下能蓋到物品的骨牌數有關。乙個骨牌能蓋到物品只和相鄰的兩個格仔是否欽...

集訓隊作業2018 GAME(並查集)

題意 題解 把這個dp式子給列出來 f i si max j f i s i max j fi si jmax 把這個字尾max max max記為m mm的話,每次就是m max m max m m max,考慮對於初始的每個m mm都維護一下,發現是條折線,維護一下這個折線,每次可以把小的一半合...