题意:n(n <= 10000)个点的带权树,统计距离<= k的点对个数。
分析:
第一道点分治...
1.求出树的重心。
2.统计通过重心的点对数量。
3.调用重心的每个儿子,去重。
4.删去重心,对每个子树递归求解。
至于统计,就是排序后,两个指针乱搞就行。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10005, M = 20005;
int n,k,e,x,y,z,siz,mx,rt,ans,l,r,sz[N],v[N],d[N],dd[N],hd[N],w[M],nxt[M],to[M];
void add(int x, int y, int z) {to[++e] = y, w[e] = z, nxt[e] = hd[x], hd[x] = e;}
void dfs(int x, int p) {
sz[x] = 1; int mxx = 0;
for(int i=hd[x];i;i=nxt[i]) if(to[i]!=p&&!v[to[i]]) dfs(to[i],x),sz[x]+=sz[to[i]],mxx=max(mxx,sz[to[i]]);
mxx = max(mxx, siz-sz[x]);
if(mxx < mx) mx = mxx, rt = x;
}
void dfs2(int x, int p) {
dd[e++] = d[x];
for(int i=hd[x];i;i=nxt[i])