NOI模擬 第k大(點分治)

2021-08-08 08:49:57 字數 1845 閱讀 9740

題意:

給一顆邊帶權的數,對於每乙個點有ki

,求從每個點出發第ki

遠的距離。

題解:

點分治。

建出點分樹並在每乙個節點儲存管轄區域的距離,在每乙個兒子節點記錄對父親的貢獻,查詢每乙個點時二分,再暴力爬樹高驗證可行性就好了。

#include

using

namespace

std;

struct io

inline

int read()

while(isdigit(ch))

return i*f;

}inline

void w(int x)

if(x<0)

while(x)buf[++buf[0]]=x%10,x/=10;

while(buf[0])

}}io;

const

int maxn=1e4+50;

typedef pair pii;

int n,k[maxn],rt,dfn[maxn],id[maxn],dis[maxn],sze[maxn],vis[maxn],ind,mx,total,g,lim,ans[maxn];

int mn[maxn*2][18],cnt,log[maxn*2],mnpos[maxn];

int nowfa[maxn];

vector

edge[maxn];

vector

len[maxn];

vector

lentofa[maxn];

inline

void dfs(int now,int f,int dist=0)

}inline

void calcg(int now,int f)

nowmx=max(nowmx,total-sze[now]);

if(nowmxinline

void getsze(int now,int f)

}inline

void getdep(int fa,int g,int now,int dist,int f)

}inline

void work(int now)

sort(len[now].begin(),len[now].end());

sort(lentofa[now].begin(),lentofa[now].end());

}inline

void splittree()

inline

int getlca(int x,int y)

inline

int getdis(int a,int b)

inline

int getans(int x,int length)

return ans;

}int main()

for(int i=1;i<=n;i++)k[i]=io.read();

dfs(1,0);

for(int i=2;i<=cnt;i++)log[i]=log[i>>1]+1;

for(int j=1;j<=15;j++)

for(int i=1;i<=cnt&&i+(1

<1

<=cnt;i++)

mn[i][j]=min(mn[i][j-1],mn[i+(1

<<(j-1))][j-1]);

splittree();

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

ans[i]=ans;

}for(int i=1;i<=n;i++)io.w(ans[i]),io.ob->sputc('\n');

}

分治演算法 尋找第k大數

問題描述 給定線性序集中n個元素和乙個整數k,1 k n,要求找出這n個元素中第k大的元素,這裡給定的線性集是無序的 其實這個問題很簡單,直接對線性序列集qsort,再找出第k個即可。但是這樣的時間複雜度就是qsort的時間複雜度o nlogn 有沒有更快的方法呢?看到網上有一種解法是採取了快排的思...

分治演算法 尋找第k大數

問題描述 給定線性序集中n個元素和乙個整數k,1 k n,要求找出這n個元素中第k大的元素,這裡給定的線性集是無序的 其實這個問題很簡單,直接對線性序列集qsort,再找出第k個即可。但是這樣的時間複雜度就是qsort的時間複雜度o nlogn 有沒有更快的方法呢?看到網上有一種解法是採取了快排的思...

分治演算法 尋找第k大數

問題描述 給定線性序集中n個元素和乙個整數k,1 k n,要求找出這n個元素中第k大的元素,這裡給定的線性集是無序的 其實這個問題很簡單,直接對線性序列集qsort,再找出第k個即可。但是這樣的時間複雜度就是qsort的時間複雜度o nlogn 有沒有更快的方法呢?看到網上有一種解法是採取了快排的思...