SPOJ-QTREE3 Query on a tree again!
2022/7/8 6:22:48
本文主要是介绍SPOJ-QTREE3 Query on a tree again!,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Query on a tree again!
树链剖分 + 二分
通过树链剖分查找,判断一下路径上,最后一个黑点出现在哪一条链上,然后在链上进行二分 dfn 查找第一个黑点所在位置
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> using namespace std; const int maxn = 1e5 + 10; int dep[maxn], siz[maxn], hson[maxn], fa[maxn]; int dfn[maxn], rnk[maxn], tr[maxn << 2], top[maxn]; vector<int>gra[maxn]; void dfs1(int now, int pre, int d) { dep[now] = d; hson[now] = -1; siz[now] = 1; fa[now] = pre; for(int i=0; i<gra[now].size(); i++) { int nex = gra[now][i]; if(nex == fa[now]) continue; dfs1(nex, now, d + 1); siz[now] += siz[nex]; if(hson[now] == -1 || siz[hson[now]] < siz[nex]) hson[now] = nex; } } int tp = 0; void dfs2(int now, int t) { tp++; top[now] = t; dfn[now] = tp; rnk[tp] = now; if(hson[now] != -1) { dfs2(hson[now], t); for(int i=0; i<gra[now].size(); i++) { int nex = gra[now][i]; if(nex == fa[now] || nex == hson[now]) continue; dfs2(nex, nex); } } } void init(int n, int rt = 1) { tp = 0; dfs1(rt, rt, 1); dfs2(rt, rt); for(int i=0; i<=n; i++) gra[i].clear(); } void update(int now, int l, int r, int x) { if(l == r) { tr[now] ^= 1; return; } int mid = l + r >> 1; if(x <= mid) update(now << 1, l, mid, x); else update(now << 1 | 1, mid + 1, r, x); tr[now] = tr[now << 1] + tr[now << 1 | 1]; } int query(int now, int l, int r, int L, int R) { if(L <= l && r <= R) return tr[now]; int mid = l + r >> 1; int ans = 0; if(L <= mid) ans += query(now << 1, l, mid, L, R); if(R > mid) ans += query(now << 1 | 1, mid + 1, r, L, R); return ans; } int solve(int v, int n) { int node = 0; while(top[v] != 1) { if(query(1, 1, n, dfn[top[v]], dfn[v])) node = v; v = fa[top[v]]; } if(query(1, 1, n, 1, dfn[v])) node = v; if(node == 0) return -1; int l = dfn[top[v]], r = dfn[v]; while(l < r) { int mid = l + r >> 1; if(query(1, 1, n, l, mid)) r = mid; else l = mid + 1; } return rnk[r]; } int main() { int n, m; scanf("%d%d", &n, &m); for(int i=1; i<n; i++) { int x, y; scanf("%d%d", &x, &y); gra[x].push_back(y); gra[y].push_back(x); } init(n, 1); while(m--) { int t; scanf("%d", &t); if(t == 0) { int i; scanf("%d", &i); update(1, 1, n, dfn[i]); } else { int v; scanf("%d", &v); printf("%d\n", solve(v, n)); } } return 0; }
这篇关于SPOJ-QTREE3 Query on a tree again!的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-22程序员出海做 AI 工具:如何用 similarweb 找到最佳流量渠道?
- 2024-12-20自建AI入门:生成模型介绍——GAN和VAE浅析
- 2024-12-20游戏引擎的进化史——从手工编码到超真实画面和人工智能
- 2024-12-20利用大型语言模型构建文本中的知识图谱:从文本到结构化数据的转换指南
- 2024-12-20揭秘百年人工智能:从深度学习到可解释AI
- 2024-12-20复杂RAG(检索增强生成)的入门介绍
- 2024-12-20基于大型语言模型的积木堆叠任务研究
- 2024-12-20从原型到生产:提升大型语言模型准确性的实战经验
- 2024-12-20啥是大模型1
- 2024-12-20英特尔的 Lunar Lake 计划:一场未竟的承诺