Blood Cousins dsu on tree + k祖先查询
作者:互联网
题意
给出一棵家谱树,定义从 u 点向上走 k 步到达的节点为 u 的 k-ancestor。多次查询,给出 u k,问有多少个与 u 具有相同 k-ancestor 的节点。
分析
这个问题我们可以离线去查询
首先我们先把每一个查询节点的k-ancesto处理出来,然后就把这个问题转化成求节点x的子树中,比他深度大k的节点有多少,就是一个树上静态统计问题了,可以用dsu on tree来进行处理
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define _CRT_SECURE_NO_WARNINGS
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC option("arch=native","tune=native","no-zero-upper")
#pragma GCC target("avx2")
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
int h[N],ne[N],e[N],idx;
int dep[N];
int cnt[N];
int son[N],Size[N],Son;
int root[N];
int f[N][21];
int ans[N];
vector<PII> q[N];
int n,m;
void add(int x,int y){
ne[idx] = h[x],e[idx] = y,h[x] = idx++;
}
void dfs(int u,int fa){
Size[u] = 1;
f[u][0] = fa;
for(int i = 1;i <= 20;i++)
f[u][i] = f[f[u][i - 1]][i - 1];
for(int i = h[u];~i;i = ne[i]){
int j = e[i];
dep[j] = dep[u] + 1;
dfs(j,u);
Size[u] += Size[j];
if(Size[son[u]] < Size[j]) son[u] = j;
}
}
int getdep(int x,int d){
int p = dep[x] - d;
for(int i = 20;~i;i--)
if(dep[f[x][i]] > p) x = f[x][i];
return f[x][0];
}
void cal(int u,int st){
cnt[dep[u]] += st;
for(int i = h[u];~i;i = ne[i]){
if(e[i] != Son)
cal(e[i],st);
}
}
void dsu(int u,bool st){
for(int i = h[u];~i;i = ne[i]){
if(e[i] != son[u]) dsu(e[i],0);
}
if(son[u]) dsu(son[u],1);
Son = son[u];
cal(u,1);
Son = 0;
for(auto t:q[u]){
int id = t.first,d = t.second;
ans[id] = cnt[dep[u] + d];
}
if(!st) cal(u,-1);
}
int main(){
memset(h,-1,sizeof h);
scanf("%d",&n);
int ll = 0;
for(int i = 1;i <= n;i++){
int fa;scanf("%d",&fa);
add(fa,i);
}
dfs(0,0);
scanf("%d",&m);
for(int i = 0;i < m;i++){
int x,y,z;
scanf("%d%d",&x,&y);
z = getdep(x,y);
if(!z){
ans[i] = 1;
continue;
}
q[z].push_back({i,y});
}
dsu(0,1);
for(int i = 0;i < m;i++) printf("%d ",ans[i] - 1);
return 0;
}
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/
标签:int,Cousins,dsu,tree,son,dep,include,Size 来源: https://blog.csdn.net/tlyzxc/article/details/110733553