luogu P3806 模板 點分治1

2022-01-09 21:46:09 字數 1784 閱讀 7026

給你一棵樹,路徑有長度,多次詢問,每次給出 k,問你是否存在路徑長度為 k 的點對。

這道題我們用分治的方法。

那我們假設要解決乙個樹,那我們先選重心作為根節點(為了減少高度節省時間)。

然後就分成兩種討論,一種是路徑都在同乙個子樹中,那這個我們就可以把問題轉換為解決這個子樹。

另一種就是在兩個不同的子樹中(或者乙個是根節點)。那我們考慮直接搜出點到根節點的距離,然後任意兩個相加都是一種可行的 \(k\)。(因為都是在不同子樹,或者是乙個是根節點的話距離就是另乙個到根節點的距離,所以是可以直接相加的)

首先,它可能是根節點,那它到根節點的距離就是 \(0\),那乙個的距離為 \(0\) 就是存在的。

然後你考慮枚舉子樹,然後求出每個點到根節點的距離。然後我們這樣弄:我們列舉每個點和你給出的詢問(也就是離線弄)的 \(y\),那首先,這個點到根節點的距離 \(x\) 一定是要小於等於 \(y\) 的,然後如果要使得這個詢問的結果是有,那距離為 \(y-x\) 的點是一定要存在的,因為這樣就可以通過這兩個,得出 \(y\) 的距離。

那你為了不會找到的點跟它是同乙個子樹中的,你就可以進行完上面的操作,才把你這個子樹的距離都標記為存在。

然後你每次不同的根統計那個存在的距離都是不同的,那你就要把之前的清空。

但是不能用 memset,因為陣列太大會超時。

但其實它真正有值的不多,那我們可以每次標記的時候把標記的點用乙個佇列記錄下來(棧也行,反正就是拿個陣列記錄值為 \(1\) 的位置),然後你要清空的時候就列舉這些值為 \(1\) 的地方,把它們賦值為 \(0\) 即可。

然後加個快讀什麼的就可以了。

#include#include#include#include#includeusing namespace std;

struct node e[200001];

struct tree t[100001];

int n, m, x, y, z, le[100001], kk;

bool in[100001], answer[101];

int ans[10000001], rem[101], que[10000001];

int d[100001], dis[100001], root;

int k, fa[100001], s, maxn[100001];

int read()

while (c >= '0' && c <= '9')

return re;

}bool cmp(int x, int y)

void add(int x, int y, int z) ; le[x] = kk;

}void find_root(int now, int father)

maxn[now] = max(maxn[now], s - t[now].s);

if (maxn[now] < maxn[root])

}void get_dis(int now, int father)

}void count_(int now)

} while (que[0])

}void dfs(int now)

}int main()

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

s = n;

maxn[0] = n;

root = 0;

find_root(1, 0);

dfs(root);

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

return 0;

}

luogu P3806 模板 點分治1

題目描述 給定一棵有n個點的樹 詢問樹上距離為k的點對是否存在。多次詢問 可離線 我們先隨意指定乙個虛擬根root,將這棵樹轉化成無根樹 樹上的路徑可以分為兩類,1.經過根節點u的路徑 2.完全在u子樹裡 不經過u 的 對於1,用dis表示當前結點到根節點root的路徑長度,則root的子樹中兩個節...

Luogu P3806 模板 點分治1

給定一棵有 n nn 個點,邊權的樹,回答 m mm 個詢問,每次詢問樹上距離為 k kk 的點對是否存在。資料範圍n 1 04,m 100,邊權 10000,k 107 n leqslant 10 4,m leqslant 100,texttt leqslant 10000,k leqslant ...

luogu P3806 模板 點分治1

給你一棵樹,路徑有長度,多次詢問,每次給出 k,問你是否存在路徑長度為 k 的點對。這道題我們用分治的方法。那我們假設要解決乙個樹,那我們先選重心作為根節點 為了減少高度節省時間 然後就分成兩種討論,一種是路徑都在同乙個子樹中,那這個我們就可以把問題轉換為解決這個子樹。另一種就是在兩個不同的子樹中 ...