caioj1443 第k小的數

2022-05-19 21:57:53 字數 1588 閱讀 1338

給出一顆n個點的樹,給出每個點的權值,再給出n-1條邊,有m個詢問,每個詢問輸入x,y,k,輸出第x節點到第y節點的路徑上第k大的點

這是一道主席樹的例題,感覺很想用樹鏈剖分,但是會超時吧......

做法就是將每個點到樹的根所形成的鏈建立線段樹,然後dfs找出點與點之間的父子關係,每個點都將自己和自己的父親,自己的父親的父親....直到根所組成的所有線段樹合併起來,然後就可以得到能夠代表區間的主席樹了,然後每當詢問輸入x,y時,就先找x和y的最近公共祖先(倍增lca來求),然後x和y的路徑其實就是x到根的路徑加上y到根的路徑,然後減去最近公共祖先到根的路徑,再減去最近公共祖先的父親到根的路徑(為什麼是最近公共祖先的父親呢,因為如果是再減去最近公共祖先到根的路徑的話,最近公共祖先就會被除去,這樣是不對的,所以減去最近公共祖先的父親到根的路徑)

#include#include

#include

#include

#include

using

namespace

std;

int s[110000],ss[110000

];struct

trnode

tr[2100000];int

cnt;

int rt[110000

];struct

edge

a[210000];int len,last[110000

];void ins(int x,int

y)int

n;int ls(int

d)

else r=mid-1

; }

return

ans;

}void link(int &u,int l,int r,int

p)void merge(int &u1,int

u2)

if(u2==0) return

; tr[u1].c+=tr[u2].c;

merge(tr[u1].lc,tr[u2].lc);

merge(tr[u1].rc,tr[u2].rc);

}int dep[110000

];int f[110000][21

];int lca(int x,int

y)

return f[x][0];}

void bt(int x,int

fa) }

}int ask(int u1,int u2,int u3,int u4,int l,int r,int

p)int

main()

sort(s+1,s+n+1

); len=0;memset(last,0,sizeof

(last));

for(int i=1;i)

cnt=0

;

for(int i=1;i<=n;i++) link(rt[i],1

,n,ls(ss[i]));

dep[

0]=0;bt(1,0

);

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

return0;

}

第k小的數

輸入n個整數和乙個正整數k 1 k n 輸出這些整數從小到大排序後的第k個 思路1 最容易想到的方法 先對這個序列從小到大排序,然後輸出前面的最小的k個數即可。如果選擇快速排序法來進行排序,則時間複雜度 o n logn class solution 時間複雜度o nlogn 思路2 在思路1的基礎...

第k小的數

time limit 5000 ms memory limit 65536 kib problem description 現有乙個包含n個整數 1 n 10000000 的無序序列 保證序列內元素各不相同 輸入乙個整數k 1 k n 請用較快的方式找出該序列的第k小數並輸出。input 多組輸入。...

第k小的數

time limit 5000 ms memory limit 65536 kib submit statistic problem description 現有乙個包含n個整數 1 n 10000000 的無序序列 保證序列內元素各不相同 輸入乙個整數k 1 k n 請用較快的方式找出該序列的第k...