首页 > 其他分享 >CF208E Blood Cousins

CF208E Blood Cousins

时间:2024-03-30 14:47:51浏览次数:17  
标签:p2 rt p1 rs int Cousins Blood CF208E ls

CF208E Blood Cousins

线段树合并

考虑把询问离线,转化题意,也就是求 \(v\) 的 \(p\) 级祖先有多少个 \(p\) 级儿子,那么询问的答案就是 「\(p\) 级祖先有多少个 \(p\) 级儿子数量 - 1」(减去自己)。\(p\) 级祖先可以倍增找到。

我们可以维护根节点的 \(k\) 级儿子。因为在遍历的过程中,子节点到根节点的深度是不变的。考虑如何合并子节点的信息,其实只需要简单的线段树合并即可。

考虑答案,显然 \(v\) 的 \(p\) 级儿子就是根节点的 \(p+now\) 级儿子,\(now\) 表示 \(v\) 的深度。

复杂度 \(O(n\log n)\)。

#include <bits/stdc++.h>
#define pii std::pair<int, int>
#define fi first
#define se second
#define pb push_back

typedef long long i64;
const int N = 1e5 + 10;
int n, m, cnt;
int h[N];
struct node {
	int to, nxt;
} e[N << 1];
void add(int u, int v) {
	e[++cnt].to = v;
	e[cnt].nxt = h[u];
	h[u] = cnt;
}
int anc[N][20], dep[N];
std::vector<pii> ve[N];
int depth, now;
void dfs(int u, int fa) {
	anc[u][0] = fa;
	dep[u] = dep[fa] + 1;
	depth = std::max(depth, dep[u]);
	for(int i = 1; i < 19; i++) {
		anc[u][i] = anc[anc[u][i - 1]][i - 1];
	}
	for(int i = h[u]; i; i = e[i].nxt) {
		int v = e[i].to;
		if(v == fa) continue;
		dfs(v, u);
	}
}
int find(int x, int y) {
	for(int i = 18; i >= 0; i--) {
		if(y >= (1 << i)) y -= (1 << i), x = anc[x][i]; 
	}
	return x;
}
int tot;
int ans[N];
struct seg {
	int ls, rs, v;
} t[N * 40];
void ins(int &u, int l, int r, int x) {
	if(!u) u = ++tot;
	if(l == r) {
		t[u].v++;
		return;
	}
	int mid = (l + r) >> 1;
	if(x <= mid) ins(t[u].ls, l, mid, x);
	else ins(t[u].rs, mid + 1, r, x);
}
void mg(int p1, int p2, int l, int r) {
	if(l == r) {
		t[p1].v += t[p2].v;
		return;
	}
	int mid = (l + r) >> 1;
	if(t[p1].ls && t[p2].ls) mg(t[p1].ls, t[p2].ls, l, mid);
	else if(t[p2].ls) t[p1].ls = t[p2].ls;
	if(t[p1].rs && t[p2].rs) mg(t[p1].rs, t[p2].rs, mid + 1, r);
	else if(t[p2].rs) t[p1].rs = t[p2].rs;
}
int query(int u, int l, int r, int x) {
	if(l == r) {return t[u].v;}
	int mid = (l + r) >> 1;
	if(x <= mid) return query(t[u].ls, l, mid, x);
	return query(t[u].rs, mid + 1, r, x);
}
void dfs2(int u, int fa) {
	now++;
	for(int i = h[u]; i; i = e[i].nxt) {
		int v = e[i].to;
		if(v == fa) continue;
		dfs2(v, u);
		mg(u, v, 1, depth);
	}
	ins(u, 1, depth, now);
	for(auto x : ve[u]) {
		ans[x.fi] = query(u, 1, depth, now + x.se) - 1;
	}
	now--;
}
std::vector<int> rt;
void Solve() {
	std::cin >> n;
	tot = n;
	for(int i = 1; i <= n; i++) {
		int x;
		std::cin >> x; 
		if(!x) rt.push_back(i);
		else add(x, i), add(i, x);
	}
	for(auto x : rt) dfs(x, 0);
	std::cin >> m;
	for(int i = 1; i <= m; i++) {
		int x, y;
		std::cin >> x >> y;
		int rt = find(x, y);
		ve[rt].push_back({i, y});
	}
	for(auto x : rt) dfs2(x, 0);
	for(int i = 1; i <= m; i++) std::cout << ans[i] << " \n"[i == m];
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
	Solve();

	return 0;
}

标签:p2,rt,p1,rs,int,Cousins,Blood,CF208E,ls
From: https://www.cnblogs.com/FireRaku/p/18105452

相关文章

  • [LeetCode] 2641. Cousins in Binary Tree II
    Giventherootofabinarytree,replacethevalueofeachnodeinthetreewiththesumofallitscousins'values.Twonodesofabinarytreearecousinsiftheyhavethesamedepthwithdifferentparents.Returntherootofthemodifiedtree.Note......
  • A Drop of Nelson's Blood.
    PopopoСвободароссийскийOh,we'dbealrightifthewindwasinoursails.噢,当风吹起我们便万事俱备!We'dbealrightifthewindwasinoursails.当风吹起我们便万事俱备!We'dbealrightifthewindwasinoursails.当风吹起我们便万事俱备!And......
  • 2023牛客暑期多校训练营8 B Bloodline Counter 指数型生成函数 容斥 多项式求逆
    传送门容易想到求出竞赛图上最大环\(\lek\)的数量,再求出\(\lek-1\)的数量作差即可得到答案。设指数型生成函数\(G(x)\)表示大小为\(i\)的环的方案数。\(G(x)=\sum_{i=1}^k\frac{a_i}{i!}x^i\)那么最大环\(\lek\)的数量\(=[x^n]n!\sum_{i=1}^ki!\frac{(G(x))^i}{i!}\)这里......
  • [Vulnhub] FIRSTBLOOD: 1
    下载地址0x00配置攻击机IP:192.168.10.5靶机IP:192.168.10.60x01攻击使用Nmap扫描靶机开放的端口┌──(root㉿azwhikaru)-[~]└─#nmap-A192.168.10.6......
  • Blood Cousins Return DSU on tree
    #include<bits/stdc++.h>usingnamespacestd;constintN=2e6+10;intn,m,Maxdep;map<string,int>name;vector<int>mp[N];vector<pair<int,int>>qus[N]......
  • 从你的全世界路过❤️——架构师frist blood
    ......
  • BloodHound学习
    一、LDAP目录服务(1)目录服务是一个特殊的数据库,用来保存描述性的、基于属性的详细信息,支持过滤功能(2)是动态的,灵活的,易扩展的。ex.电话簿、地址簿LDAP......
  • 学习笔记-BloodHound
    BloodHound免责声明本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关.简介BloodHound可以在域内导出相关信息,将......
  • 记一次修复BloodHound导入数据失败问题
    我的BloodHound在大概2021年就安装了,之后没用过几回。最近由于一些内网渗透学习的原因,又重回BloodHound的怀抱。但很显然,他并不友好。我在信息收集结束后,尝试导入数据,却发......
  • Codeforces Round #151 (Div. 2) E Blood Cousins Return
    BloodCousinsReturn启发式合并在跑启发式合并的同时,对每个深度都维护一个\(set\),就可以自动去重并计算有多少种不同的字符串#include<iostream>#include<cstdio>......