题解:P7126 [Ynoi2008] rdCcot

news/2025/9/29 19:02:55/文章来源:https://www.cnblogs.com/LUlululu1616/p/19119334

题意:很简单了,不再赘述。

做法:

考虑怎么数连通块,钦定一个代表元,因为这个东西是 \(C\) 邻域状物,跟深度有关,我们可以考虑一下 bfs 序,那么我们就以 bfs 序最小的元素为代表元。

然后我们就要考虑一个元素什么时候是代表元,接下来我们会证明,对于一个元素,如果点 \(u\) 不和 bfs 序小于他的点连边,那么他就是代表元。

首先我们需要先证明一个结论:考虑对于 \(bfn_{i}<bfn_j<bfn_k,(i,k),(j,k)\) 间有边,则 \((i,j)\) 间也有边。

考虑 \(d = lca(i,k)\),如果 \(j\)\(d\) 子树内,那么 \(dep_j\le dep_k\),所以 \(dis(i,k)\ge dis(i,j)\),那么有边;而若在子树外,因为 \(dep_i\le dep_k\),所以 \(dis(j,k)\ge dis(i,j)\),所以也有边。

接下来我们证明上面的东西,考虑如果现在有一条路径 \(u\rightarrow a_1\rightarrow a_2\rightarrow\cdots\rightarrow a_k\rightarrow v\)满足 \(bfn_u>bfn_v\),那么我们就可以按上面那个结论,把这个路径的 \(bfn\) 写出来,就等于每次我可以缩掉一个峰,一直缩就可以证明这个结论。

所以我们现在只需要求出来满足对于 \(i\),下标小于 \(i\) 且 bfs 序更小,与 \(i\) 有连边的下标最大的元素 \(l_i\),类似定义 \(r_i\),那么最后询问区间 \([L,R]\) 时,只需要算 \(l_i<L,r_i>R,L\le i\le R\) 的有多少个,这个可以扫描线,在 \(i\) 处对区间 \([l_i+1,i]\) 加一,在 \(r_i\) 处减一,询问单点查就可以。

那么怎么计算 \(l_i,r_i\) 呢?因为这个东西需要满足 \(dis(i,l_i)\le C\),所以我们考虑用淀粉质来做,然后按 bfn 序排序。我们维护一颗平衡树,这里我用的是 FHQ Treap,按照点的编号从小到大,然后在每一个节点上维护字数内距离当前分治中心最小距离是多少。在插入一个点的时候,先将编号小于和大于的两部分分裂,分别去找编号最大/最小的满足距离限制的点即可。

这个题有点卡常,一点卡常小技巧是,分治时如果扫到一个点距离分治中心大于 \(C\),那么就没有必要让剩下子树去计算 \(l_i,r_i\),显然是没有贡献的。

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 6e5 + 5;
int n, m, c, bfn[maxn / 2], tot, f[maxn / 2];
vector<int> e[maxn];
void bfs(int s) {queue<int> q;q.push(s);while(!q.empty()) {int u = q.front(); bfn[u] = ++tot; q.pop();for (int i = 0; i < e[u].size(); i++) {int v = e[u][i];if(v == f[u])continue;f[v] = u, q.push(v);}}
}
int dis[maxn / 2], l[maxn / 2], r[maxn / 2];
mt19937 rnd(time(0));
struct node {int l, r, del, pos, res, v;node() {l = r = 0, del = rnd();res = 0, v = 0;}
} ;
struct Treap {node tr[maxn / 2];int tot, rt;	inline int newnode(int u) {tr[++tot] = node();tr[tot].pos = u, tr[tot].res = tr[tot].v = dis[u];return tot;}inline void pushup(int u) {tr[u].res = min(min(tr[tr[u].l].res, tr[tr[u].r].res), tr[u].v);}void split(int p, int &l, int &r, int k) {if(!p) {l = r = 0;return ;}if(tr[p].pos <= k) l = p, split(tr[p].r, tr[l].r, r, k);elser = p, split(tr[p].l, l, tr[r].l, k);pushup(p);}int mrg(int l, int r) {if(!l || !r)return l + r;int p;if(tr[l].del > tr[r].del) p = l, tr[l].r = mrg(tr[l].r, r);elsep = r, tr[r].l = mrg(l, tr[r].l);pushup(p);return p;}int query_getposl(int u, int lim) {//	cout << u << endl;if(tr[u].res > lim || !u) {// 		cout << u << endl;return 0;}if(tr[tr[u].r].res <= lim)return query_getposl(tr[u].r, lim);if(tr[u].v <= lim)return tr[u].pos;return query_getposl(tr[u].l, lim);}int query_getposr(int u, int lim) {if(tr[u].res > lim || !u)return n + 1;if(tr[tr[u].l].res <= lim)return query_getposr(tr[u].l, lim);if(tr[u].v <= lim)return tr[u].pos;return query_getposr(tr[u].r, lim);} inline void insert(int u) {int p = newnode(u), p1, p2;split(rt, p1, p2, u);int v1 = query_getposl(p1, c - dis[u]), v2 = query_getposr(p2, c - dis[u]);l[u] = max(l[u], v1);r[u] = min(r[u], v2);rt = mrg(mrg(p1, p), p2);}inline void clear() {rt = tot = 0;tr[0].res = 2e9;}
} tree;
int sz[maxn / 2], rt, all, mx;
bool vis[maxn / 2];
void getsz(int u, int fa) {sz[u] = 1; all++;
//	cout << u << endl;for (int i = 0; i < e[u].size(); i++) {int v = e[u][i];if(v == fa || vis[v])continue;getsz(v, u);sz[u] += sz[v];}
}
void getrt(int u, int fa) {int res = all - sz[u];for (int i = 0; i < e[u].size(); i++) {int v = e[u][i];if(v == fa || vis[v])continue;getrt(v, u);res = max(res, sz[v]);}if(res < mx)mx = res, rt = u;
}
int getroot(int u) {rt = all = 0, mx = 2e9;getsz(u, 0), getrt(u, 0);return rt;
}
bool cmp(int x, int y) {return bfn[x] < bfn[y];
}
vector<int> pos;
void add(int u, int fa) {if(dis[u] > c)return ;pos.push_back(u);for (int i = 0; i < e[u].size(); i++) {int v = e[u][i];if(v == fa || vis[v])continue;dis[v] = dis[u] + 1;add(v, u);}
}
void solve(int u) {
//	cout << u << endl;vis[u] = 1; dis[u] = 0;pos.clear(), add(u, 0); tree.clear();sort(pos.begin(), pos.end(), cmp);for (int i = 0; i < pos.size(); i++)tree.insert(pos[i]);for (int i = 0; i < e[u].size(); i++) {int v = e[u][i];if(vis[v])continue;solve(getroot(v));}
}
#define lowbit(x) (x & (-x))
struct Segtree {int tr[maxn / 2];inline void add(int x, int val) {while(x <= n)tr[x] += val, x += lowbit(x);}inline int query(int x) {int ans = 0;while(x)ans += tr[x], x -= lowbit(x);return ans;}inline int queryseg(int l, int r) {return query(r) - query(l - 1);}inline void addseg(int l, int r, int v) {add(l, v), add(r + 1, -v);}
} tree1;
int lq[maxn], rq[maxn], ans[maxn];
vector<int> post[maxn / 2], qry[maxn / 2];
inline int read() {int sum = 0; char c = getchar();while(!isdigit(c))c = getchar();while(isdigit(c))sum = sum * 10 + c - '0', c = getchar();return sum;
}
void write(int x) {if(x <= 9) {putchar(x + '0');return ;}write(x / 10);putchar(x % 10 + '0');
}
signed main() {n = read(), m = read(), c = read();for (int x, i = 2; i <= n; i++)x = read(), e[x].push_back(i), e[i].push_back(x);bfs(1);for (int i = 1; i <= n; i++)l[i] = 0, r[i] = n + 1;solve(getroot(1));for (int i = 1; i <= m; i++)lq[i] = read(), rq[i] = read(), qry[rq[i]].push_back(i);for (int i = 1; i <= n; i++)post[i].push_back(i), post[r[i]].push_back(-i);for (int i = 1; i <= n; i++) {for (int j = 0; j < post[i].size(); j++) {int id = post[i][j];if(id > 0)tree1.addseg(l[id] + 1, id, 1);elsetree1.addseg(l[-id] + 1, -id, -1);}for (int j = 0; j < qry[i].size(); j++)ans[qry[i][j]] = tree1.queryseg(1, lq[qry[i][j]]);}for (int i = 1; i <= m; i++)write(ans[i]), putchar('\n');return 0;
}
/*
9 6 5 
1 2 3 4 5 6 7 8
1 2
1 3
2 4 
3 9 
6 8
1 6
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/922141.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里云网站 模板建设装修公司报价如何计算

查看源码发现 PHP非法参数名传参问题&#xff0c;详细请参考我的这篇文章&#xff1a;谈一谈PHP中关于非法参数名传参问题 正则这里绕过使用%0a换行符绕过&#xff0c;payload: /?b.u.p.t23333%0a 得到下一步信息&#xff1a;secrettw.php 注释中的是JsFuck&#xff0c;用这…

网站开发项目拖延周期免费建设视频网站

作者 | 徐运元&#xff0c;杭州谐云科技合伙人及资深架构师&#xff0c;云计算行业和 Kubernetes 生态资深从业者 导读&#xff1a;什么是 OAM&#xff1f;2019 年 10 月 17 日&#xff0c;阿里巴巴合伙人、阿里云智能基础产品事业部总经理蒋江伟&#xff08;花名&#xff1a;小…

毕业答辩为什么做网站网站建设云技术公司推荐

1.PC按键控制 移动摄像头:WSADQE、鼠标右键 模拟双手:左手(左Shift)、右手(右Shift) 将模拟的双手保持在视野中:T或Y 旋转模拟手部:按住Ctrl并移动鼠标 捏合手势:左Shift/空格 + 鼠标左键 2.常用脚本 (1)HandInteractionTouch(需搭配NearInteractionTouchableVolum…

专业的网站开发团队xampp php网站模板

相关免费学习推荐&#xff1a;python视频教程原理十进制转n进制都可以使用倒除法&#xff1a;对十进制进行除n的运算&#xff0c;直到商为0为止&#xff0c;然后将各个步骤中得到的余数倒着写出来.n进制转十进制&#xff1a;(例子&#xff1a;二进制转十进制)101001 > 2^5 …

灰系网站深圳建站公司兴田德润放心

.gitignore简介 .gitignore文件是Git 版本控制系统中的一个重要配置文件&#xff0c;它用于指定哪些文件或目录应该被Git忽略&#xff0c;即不被纳入版本控制中。 .gitignore编写规则 在文件中添加要忽略的文件和目录的模式。每一行表示一个模式。 使用通配符来匹配多个文件或目…

网站备案 备注关联性沈阳男科最好的男科医院

1、首先配置正确Project Struct 保证需要引用的jar包库添加到Libraries里&#xff0c;尽管添加到Modules里依然可以测试运行或调试&#xff0c;但导出的jar包会遇到问题。 2、导出jar&#xff0c;方式选择如下 选择”From modules with dependencies" 然后去掉以上“Extr…

MyBatis技术详解:从入门到高效开发 - 详解

MyBatis技术详解:从入门到高效开发 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "…

做美食网站有哪些网络广告策略有哪些

本博客主要讲述Center的审计策略表安装和策略添加 使用事务添加 1、开启事务 my->StartTransaction(); 2、编写sql语句 //清除原来数据&#xff0c;防止数据污染my->Query("DROP TABLE IF EXISTS t_strategy");string sql "CREATE TABLE t_strategy (…

解码数据结构队列

队列的基础原理 核心定义与原则本质:队列(Queue)是线性结构,与栈同属线性存储,核心差异在于操作原则:栈遵循 “后进先出(LIFO)”,仅允许一端操作; 队列遵循 “先进先出(FIFO,First Input First Output)”,…

实用指南:Linux Shell 脚本:从零到进阶的实战笔记

实用指南:Linux Shell 脚本:从零到进阶的实战笔记pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…

解决升级 Windows 11 24H2 后 NAS 共享无法显示的问题

问题原因 Windows 11 24H2 策略强制默认只能访问签名的 SMB 共享用户,并且不允许使用 不安全的来宾(Guest)登录 模式连接文件共享。 解决方法 终端管理员模式下依次运行: Set-SmbClientConfiguration -RequireSecu…

实用指南:汽车地带AutoZone EDI需求分析及对接指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

商城类电商购物APP网购原型——实战计划原型

商城类电商购物APP网购原型——实战计划原型2025-09-29 18:42 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: bl…

怎样登录建设银行官方网站楼盘网站建设方案

写在前面 考试顺便整理博文内容整理 使用 Ansible 部署 samba 客户端和服务端理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&#xff0c;永不停息。所有其它的路都是不完整的&#xff0c…

【还未找到原题】宝石(GEM) - Harvey

【还未找到原题】宝石(GEM)题意 给定 \(m\) 对关系,表示 \(a\) 比 \(b\) 小,此时问最先确定每一个点的排名的关系最小编号,如果最后还未确定排名,则此点输出-1。 由于没有原题,给个样例: input: 4 4 2 4 3 1 4…

第八篇

今天是9月29日,今天是满课,上午上的是统一建模语言和算法与数据,下午上的是Java,收获颇丰,上午明白了链表的增删改查,下午Java练习了编程。

C# AStar 算法 - 实际应用

在基本实现中 我们的理想化 是方格坐标的,但是实际应用可能是跨点的坐标,所以需要以 路段为核心,并且路段也支持了 方向的限制。 如果处于转弯的话,也优化了转弯的权重,尽量少转弯。 其中距离计算可以根据需要自行…

nocobase 源码安装

Git 源码安装 0. 先决条件 请确保你已经:安装了 Git、Node.js 20+、Yarn 1.22.x 配置并启动了所需数据库 MySQL 8.0.17+、MariaDB 10.9+、PostgreSQL 10+ 任选其一1. 将 NocoBase 下载到本地 latest 版本 (main) 功能…

南宁网站推广系统怎么做网站缩略图

关注我们谈到 .NET 在中国的推广和发展&#xff0c;.NET 开发者求职就业及 .NET 企业招人用人的问题往往常被提及。初学者会担心学习 .NET 之后的就业问题&#xff0c;.NET 开发者在求职过程中没有足够多的渠道来获取 .NET 招聘信息&#xff0c;而与此同时&#xff0c;采用 .NE…

小城建设的网站东莞出行政策有变了

大模型撬动数据新质生产力&#xff0c; 我们重新解构了智能BI 作者 | 曾响铃 文 | 响铃说&#xff08;xiangling0815&#xff09; “超级人工智能将在‘几千天内’降临。” 最近&#xff0c;OpenAI 公司 CEO 山姆奥特曼在社交媒体罕见发表长文&#xff0c;预言了这一点。之前…