【树论典题。】P6071 『MdOI R1』Treequery
1.P2048 [NOI2010] 超级钢琴 RMQ + Heap2.【CDQ分治】 CF641E3.生活在树上(hard version) 树上差分4.【牛逼做法】P4186 Cow at Large5.P3519 [POI2011]ROZ-Difference6.【CF1146F】Leaf Partition7.【CF1715E】Long Way Home8.【CF678F】Lena and Queries9.【CF1797F】Li Hua and Path10.P9170 填数游戏 贺题记录11.P7316 [COCI2018-2019#3] NLO12.P5471 [NOI2019] 弹跳13.【经典例题】P6822 [PA2012] Tax14.【差分 Trick】CF626F Group Projects15.CF1556G Gates to Another World
16.【树论典题。】P6071 『MdOI R1』Treequery
17.神秘哈希题。18.【树论,计数】Centroid Probabilities19.【Tricks,典】[ARC085F] NRE20.【拆贡献】CF1422F Boring Queries21.【OGF、Lucas】P4640 [BJWC2008] 王之财宝22.【Quick Hull】P3236 [HNOI2014] 画框23.【很难啊、拆分数、观察】P6944 [ICPC2018 WF] Gem Island24.「突刺贯穿第二分块」P4117 [Ynoi2018] 五彩斑斓的世界25. 【LCT 维护子树信息】CF916E Jamie and Tree26.【线段树合并、虚树】P5327 [ZJOI2019] 语言27.【树套树,LCT,出栈序】P4027 [NOI2007] 货币兑换28.【边双,dp】P8867 [NOIP2022] 建造军营29.【历史和】P8868 [NOIP2022] 比赛30.CF1083D31.CF1486F32.[HNOI2015] 开店33.【LCT、树状数组】CF1137F Matches Are Not a Child's Play34.【链交理论】CF1336F Journey35.【树论典题】P5642 人造情感(emotion)36.【友谊就是魔法!!】CF453E37.CF1109E、CF1109F38.P10083 [GDKOI2024 提高组] 不休陀螺39.洛谷博客杂题 #1前言:
输了,被水杯提醒我一直很失败。
正片:
简要题意
求 的路径的交的边权和。
Solution: 巨大分讨做法。
考虑分类讨论。
其一, 根本就不属于路径上的点,这个求区间 LCA 可以解决
其二, 是 的祖先,显然,还是上面那个。
其三, 子树内有 的点,直接为 0 即可,因为这样是没有交的。
其四, 但不属于三,这个考虑倍增,求一个祖先满足三的情况即可。
这些全部都需要子树与区间交的技术,这个直接考虑二维数点,固定编号一维主席树数点即可,这个就是狼人。
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l; i <= r; i ++)
#define per(i, r, l) for (int i = r; i >= l; i --)
#define ll long long
// 出题人小黑子树脂 66
using namespace std;
const int _ = 2e5 + 5;
struct EDGE { int y, z; } ;
vector <EDGE> e[_];
int n, q, dfc;
int pa[_][20], son[_], dis[_], dep[_], dfn[_], sz[_], top[_];
int lg[_], st[_][20];
void dfs1 (int x, int fa) {
dep[x] = dep[fa] + 1, sz[x] = 1;
pa[x][0] = fa;
rep(i, 1, 19) pa[x][i] = pa[pa[x][i - 1]][i - 1];
for (auto & [y, z] : e[x]) {
if (y == fa) continue ;
dis[y] = dis[x] + z,
dfs1(y, x), sz[x] += sz[y];
if (sz[son[x]] < sz[y]) son[x] = y;
}
}
void dfs2 (int x, int fa, int anc) {
dfn[x] = ++ dfc, top[x] = anc;
if (son[x]) dfs2(son[x], x, anc);
for (auto & [y, z] : e[x])
if (y != fa && y != son[x]) dfs2(y, x, y);
}
int queryLCA (int x, int y) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
x = pa[top[x]][0];
}
return dep[x] < dep[y] ? x : y;
}
int RangeLCA (int l, int r) {
int k = lg[r - l + 1];
return queryLCA(st[l][k], st[r - (1 << k) + 1][k]);
}
int rt[_], tot;
namespace tr {
struct node {
int lc, rc, s;
} t[_ * 25];
void modify (int & x, int y, int l, int r, int k) {
x = ++ tot, t[x] = t[y], t[x].s ++;
if (l == r) return ;
int mid = (l + r) >> 1;
if (k <= mid) modify(t[x].lc, t[y].lc, l, mid, k);
else modify(t[x].rc, t[y].rc, mid + 1, r, k);
}
int query (int x, int l, int r, int ql, int qr) {
if (!x) return 0;
if (ql <= l && r <= qr) return t[x].s;
int mid = (l + r) >> 1, ret = 0;
if (ql <= mid) ret += query(t[x].lc, l, mid, ql, qr);
if (qr > mid) ret += query(t[x].rc, mid + 1, r, ql, qr);
return ret;
}
int insec (int x, int ql, int qr) {
return query(rt[qr], 1, n, dfn[x], dfn[x] + sz[x] - 1) -
query(rt[ql - 1], 1, n, dfn[x], dfn[x] + sz[x] - 1);
}
}
void build () {
dfs1(1, 1), dfs2(1, 0, 1), lg[0] = -1;
rep(i, 1, n) lg[i] = lg[i >> 1] + 1, st[i][0] = i;
rep(k, 1, 19) rep(i, 1, n - (1 << k) + 1)
st[i][k] = queryLCA(st[i][k - 1], st[i + (1 << k - 1)][k - 1]);
rep(x, 1, n) tr::modify(rt[x], rt[x - 1], 1, n, dfn[x]);
}
int dist (int x, int y) { return dis[x] + dis[y] - dis[queryLCA(x, y)] * 2; }
int findanc (int x, int l, int r) {
int p;
for (int i = 19; i >= 0; i --) {
int p = pa[x][i];
// cout << " " << p;
// if (! p) continue ;
if (! tr::insec(p, l, r)) x = p;
}
return pa[x][0];
}
#define bel(x, y) (dfn[x] >= dfn[y] && dfn[x] < sz[y] + dfn[y])
int main () {
cin >> n >> q;
rep(i, 1, n - 1) {
int x, y, z;
scanf("%d%d%d", & x, & y, & z);
e[x].push_back({y, z}), e[y].push_back({x, z});
}
build();
int p, l, r, lst = 0;
while(q --) {
scanf("%d%d%d", & p, & l, & r);
p ^= lst, l ^= lst, r ^= lst;
int anc = RangeLCA(l, r),
cnt = tr::insec(p, l, r);
if (bel(anc, p) || !bel(p, anc)) lst = dist(p, anc);
else if (cnt) lst = 0;
else {
int t = findanc(p, l, r);
lst = dist(p, t);
}
// cout << endl;
printf("%d\n", lst);
}
return 0;
}
登高自卑,行远自迩。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话