当前位置: 首页 > news >正文

P11967 [GESP202503 八级] 割裂 题解

我讨厌倍增 lca, 因此提供一种非倍增做法。

首先我们先解析题意。相当于在一棵树上给你一条链 A,然后又给你一个有着若干条链的集合 B。问你在 A 上的节点有多少个不存在于集合 B 中的任意链上。

前置的一个知识是我们如何不利用倍增来找在一条链上的点。

我们发现,一个点 s 在链 x, y上,当且仅当

(lca(s,x) == s || lca(s,y) == s) && dep[s] >= dep[lca(x, y)]

自己手玩一棵树就可以得到,不讲解。

那么其实这题已经做完了。我们用树上差分处理出对于每个点, B 里的链经过这个点的次数。

然后判断通过刚才的方法判断这个点是不是在链 A 上。

lca 采用 \(O(1)\) lca。

#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
const int N = 1000005;
int ans, n, a, x, y, z, target, cnt, b1, b2, dfn[N], dep[N], st[N][26], mark[N], father[N];
vector<int> e[N];
void dfs(int s, int fa) {father[s] = fa;dep[s] = dep[fa] + 1;dfn[s] = ++cnt;st[dfn[s]][0] = fa;for(const int to : e[s]) {if(to == fa) continue;dfs(to, s);}
}
inline int get(int x, int y) {return dep[x] < dep[y] ? x : y;}
void init() {for(int i = 1; (1 << i) <= n; ++i) {rep(j, 1, n) {if(j + (1 << i) - 1 > n) break;st[j][i] = get(st[j][i - 1], st[j + (1 << i - 1)][i - 1]);}}
}
inline int lca(int x, int y) {if(x == y) return x;x = dfn[x], y = dfn[y];if(x > y) swap(x, y);int len = __lg(y - x);return get(st[x + 1][len], st[y - (1 << len) + 1][len]);
}
void dfs2(int s) {for(const int to : e[s]) {if(to == father[s]) continue;dfs2(to);mark[s] += mark[to];}x = lca(s, b1), y = lca(s, b2);if(!mark[s] && ((x == s || (y == s))) && dep[s] >= dep[target]) ++ans;
}
int main() {cin >> n >> a;rep(i, 1, n - 1) {cin >> x >> y;e[x].push_back(y);e[y].push_back(x);}dfs(1, 0);init();rep(i, 1, a) {cin >> x >> y;z = lca(x, y);++mark[x], ++mark[y];--mark[z], --mark[father[z]];}cin >> b1 >> b2;target = lca(b1, b2);dfs2(1);cout << ans;return 0;
}

复杂度 \(O(n\log n + a)\), 常数略大。

http://www.hskmm.com/?act=detail&tid=1239

相关文章:

  • 变量和运算符和类型
  • win 图片和视频文件无法显示缩略图如何解决?
  • 输入和输出
  • 三种语句
  • 力扣第5题最长回文子串
  • 用 Python 和 PaddleOCR 进行验证码识别
  • TASK 1 训练一个网络识别手写数字
  • 复杂背景验证码的识别思路与图像处理方法
  • Symfony学习笔记 - The Symfony Framework Best Practices
  • 大学军训
  • Vue Day3【综合案例2】vue小兔鲜儿
  • Java 基础知识解析
  • 力扣第3题 无重复字符的最长子串
  • UniApp 自定义导航栏
  • P3177 [HAOI2015] 树上染色
  • UniApp 自定义tabBar
  • NOIP2024复盘
  • Avalonia 学习笔记04. Page Navigation(页面导航) (转载)
  • 判断左手坐标系和右手坐标系的方法
  • 题解:P11894 「LAOI-9」Update
  • 题解:P2012 拯救世界2
  • 一键安装小雅Alist
  • 题解:AT_abc394_c [ABC394C] Debug
  • Lumion Pro 12.0 下载安装教程包含安装包下载、安装、激活超详细图文步骤
  • 题解:CF348C Subset Sums
  • 题解:CF351B Jeff and Furik
  • 题解:CF2118D1 Red Light, Green Light (Easy version)
  • js和vue的数据类型
  • 202508 组合计数专题 笔记
  • python解释器位数与电脑的关系