[洛谷P4092][HEOI2016/TJOI2016]树
题目大意:给你一棵树,有两个操作:
- $C\;x:$给第$x$个节点打上标记
- $Q\;x:$询问第$x$个节点的祖先中最近的打过标记的点(自己也是自己的祖先)
题解:树剖,可以维护区间或,然后若一段区间为$0$则跳过,否则在线段树上二分
卡点:二分部分多大了一个$=$,然后$MLE$
C++ Code:
#include <cstdio>
#include <algorithm>
#include <ctime>
#include <cctype>
#include <cstdlib>
namespace __IO {
namespace R {
int x, ch;
inline int read() {
ch = getchar();
while (isspace(ch)) ch = getchar();
for (x = ch & 15, ch = getchar(); isdigit(ch); ch = getchar()) x= x * 10 + (ch & 15);
return x;
}
inline char readc() {
ch = getchar();
while (!isalpha(ch)) ch = getchar();
return static_cast<char> (ch);
}
}
}
using __IO::R::read;
using __IO::R::readc; #define maxn 100010
int head[maxn], cnt;
struct Edge {
int to, nxt;
} e[maxn << 1];
inline void add(int a, int b) {
e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
e[++cnt] = (Edge) {a, head[b]}; head[b] = cnt;
} int n, m; int dfn[maxn], idx, fa[maxn], sz[maxn];
int son[maxn], top[maxn], dep[maxn], ret[maxn];
void dfs1(int u) {
sz[u] = 1;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != fa[u]) {
dep[v] = dep[u] + 1;
fa[v] = u;
dfs1(v);
if (!son[u] || sz[v] > sz[son[u]]) son[u] = v;
sz[u] += sz[v];
}
}
}
void dfs2(int u) {
dfn[u] = ++idx, ret[idx] = u;
int v = son[u];
if (v) top[v] = top[u], dfs2(v);
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != son[u] && v != fa[u]) {
top[v] = v;
dfs2(v);
}
}
} namespace SgT {
bool V[maxn << 2];
int pos, L, R; void modify(int rt, int l, int r) {
V[rt] = true;
if (l == r) return ;
int mid = l + r >> 1;
if (pos <= mid) modify(rt << 1, l, mid);
else modify(rt << 1 | 1, mid + 1, r);
}
void modify(int __pos) {
pos = __pos;
modify(1, 1, n);
} bool res;
void query(int rt, int l, int r) {
if (L <= l && R >= r) return static_cast<void> (res |= V[rt]);
int mid = l + r >> 1;
if (L <= mid) query(rt << 1, l, mid);
if (res) return ;
if (R > mid) query(rt << 1 | 1, mid + 1, r);
}
bool query(int __L, int __R) {
res = false;
L = __L, R = __R;
query(1, 1, n);
return res;
} int ans;
void ask(int rt, int l, int r) {
if (!V[rt]) return ;
if (l == r) {
if (!ans) ans = l;
return ;
}
int mid = l + r >> 1;
if (R > mid) ask(rt << 1 | 1, mid + 1, r);
if (ans) return ;
if (L <= mid) ask(rt << 1, l, mid);
}
int ask(int __L, int __R) {
L = __L, R = __R;
ans = 0;
ask(1, 1, n);
return ret[ans];
}
} int query(int x) {
while (top[x] != 1) {
if (SgT::query(dfn[top[x]], dfn[x])) return SgT::ask(dfn[top[x]], dfn[x]);
x = fa[top[x]];
}
return SgT::ask(1, dfn[x]);
} int main() {
n = read(), m = read();
for (int i = 1, a, b; i < n; i++) {
a = read(), b = read();
add(a, b);
}
dfs1(1);
top[1] = 1;
dfs2(1); SgT::modify(1);
while (m --> 0) {
char op = readc();
int x = read();
if (op == 'C') {
SgT::modify(dfn[x]);
} else {
printf("%d\n", query(x));
}
}
return 0;
}
[洛谷P4092][HEOI2016/TJOI2016]树的更多相关文章
- 洛谷 P4092 [HEOI2016/TJOI2016]树 || bzoj4551
https://www.lydsy.com/JudgeOnline/problem.php?id=4551 https://www.luogu.org/problemnew/show/P4092 这当 ...
- 洛谷P4092 [HEOI2016/TJOI2016]树 并查集/树链剖分+线段树
正解:并查集/树链剖分+线段树 解题报告: 传送门 感觉并查集的那个方法挺妙的,,,刚好又要复习下树剖了,所以就写个题解好了QwQ 首先说下并查集的方法趴QwQ 首先离线,读入所有操作,然后dfs遍历 ...
- 洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP
洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他. 玩具上有一个数列,数列中某些项的值可能会 ...
- 洛谷 P4093 [HEOI2016/TJOI2016]序列 解题报告
P4093 [HEOI2016/TJOI2016]序列 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能会变化,但同一个时刻最多只有一 ...
- 洛谷 P2824 [HEOI2016/TJOI2016]排序 解题报告
P2824 [HEOI2016/TJOI2016]排序 题意: 有一个长度为\(n\)的1-n的排列\(m\)次操作 \((0,l,r)\)表示序列从\(l\)到\(r\)降序 \((1,l,r)\) ...
- BZOJ4553/洛谷P4093 [HEOI2016/TJOI2016]序列 动态规划 分治
原文链接http://www.cnblogs.com/zhouzhendong/p/8672434.html 题目传送门 - BZOJ4553 题目传送门 - 洛谷P4093 题解 设$Li$表示第$ ...
- 洛谷 P4091 [HEOI2016/TJOI2016]求和 解题报告
P4091 [HEOI2016/TJOI2016]求和 题目描述 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: \[ f(n)=\sum_{i=0}^n\ ...
- 洛谷P2824 [HEOI2016/TJOI2016]排序(线段树)
传送门 这题的思路好清奇 因为只有一次查询,我们考虑二分这个值为多少 将原序列转化为一个$01$序列,如果原序列上的值大于$mid$则为$1$否则为$0$ 那么排序就可以用线段树优化,设该区间内$1$ ...
- 洛谷 P2824 [HEOI2016/TJOI2016]排序 (线段树合并)
(另外:题解中有一种思路很高妙而且看上去可以适用一些其他情况的离线方法) 线段树合并&复杂度的简单说明:https://blog.csdn.net/zawedx/article/details ...
随机推荐
- linux下实现ssh无密码登录访问
在192.168.9.51机器上 1)运行:#ssh-keygen -t rsa 2)然后拍两下回车(均选择默认) 3)运行: #ssh-copy-id -i /root/.ssh/id_rsa.pu ...
- 限时购校验小工具&dubbo异步调用实现限
本文来自网易云社区 作者:张伟 背景 限时购是网易考拉目前比较常用的促销形式,但是前期创建一个限时购活动时需要各个BU按照指定的Excel格式进行选品提报,为了保证提报数据准确,运营需要人肉校验很多信 ...
- python爬虫实例大全
WechatSogou [1]- 微信公众号爬虫.基于搜狗微信搜索的微信公众号爬虫接口,可以扩展成基于搜狗搜索的爬虫,返回结果是列表,每一项均是公众号具体信息字典. DouBanSpider [2]- ...
- beauifulsoup模块的介绍
01 爬虫基础知识介绍 相关库:1.requests,re 2.BeautifulSoup 3.hackhttp 使用requests发起get,post请求,获取状态码,内容: 使用re匹 ...
- Java开发工程师(Web方向) - 02.Servlet技术 - 期末考试
Servlet课程考试 Servlet课程考试 Servlet课程考试 总分:55分 限定时间:120分钟 进入考试 答案已成功提交!请耐心等待成绩公布 Servlet课程考试: 1(12分) 简单谈 ...
- CF245H Queries for Number of Palindromes
题目描述 给你一个字符串s由小写字母组成,有q组询问,每组询问给你两个数,l和r,问在字符串区间l到r的字串中,包含多少回文串. 时空限制 5000ms,256MB 输入格式 第1行,给出s,s的长度 ...
- 【Random】-随机数字-jmeter
参数化 Random 参数化,存储结果的变量名,名字写了,就可以给其它请求使用
- [SHELL]结构化命令之条件语句
1.if-then语句 #!/bin/bash username="root" if grep $username /etc/passwd then echo "the ...
- 深入理解 Vuejs 动画效果
本文主要归纳在 Vuejs 学习过程中对于 Vuejs 动画效果的各个相关要点.由于本人水平有限,如文中出现错误请多多包涵并指正,感谢.如果需要看更清晰的代码高亮,请跳转至我的个人站点的 深入理解 V ...
- 简单构建基于RDF和SPARQL的KBQA(知识图谱问答系统)
本文主要通过python实例讲解基于RDF和SPARQL的KBQA系统的构建.该项目可在python2和python3上运行通过. 注:KBQA即是我们通常所说的基于知识图谱的问答系统.这里简单构建的 ...