[bzoj4551][Tjoi2016&Heoi2016]树-树链剖分
Brief Description
给定一颗有根树(根为1),有以下
两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个
结点,可以打多次标记。)2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖
先)你能帮帮他吗?
Algorithm Design
树链剖分维护最深层带标记节点.
裸, 1A, 高兴.
Code
#include <cstdio>
#define init int l = t[k].l, r = t[k].r, mid = (l + r) >> 1
const int maxn = 201000;
int n, Q, cnt;
struct edge {
int to, next;
} e[maxn << 1];
struct seg {
int l, r, data;
} t[maxn << 2];
int head[maxn], q[maxn], bl[maxn], belong[maxn], size[maxn], dfn, like[maxn],
tag[maxn], fa[maxn], deep[maxn];
void add_edge(int u, int v) {
e[++cnt].to = v;
e[cnt].next = head[u];
head[u] = cnt;
}
void dfs1(int x) {
size[x] = 1;
for (int i = head[x]; i; i = e[i].next) {
if (e[i].to != fa[x]) {
fa[e[i].to] = x;
deep[e[i].to] = deep[x] + 1;
dfs1(e[i].to);
size[x] += size[e[i].to];
if (size[e[i].to] > size[like[x]])
like[x] = e[i].to;
}
}
}
void dfs2(int x, int chain) {
bl[x] = ++dfn;
q[dfn] = x;
belong[x] = chain;
if (like[x])
dfs2(like[x], chain);
for (int i = head[x]; i; i = e[i].next) {
if (e[i].to != fa[x] && e[i].to != like[x]) {
dfs2(e[i].to, e[i].to);
}
}
}
void build(int k, int l, int r) {
t[k].l = l, t[k].r = r, t[k].data = (l <= 1 && 1 <= r) ? 1 : 0;
if (l == r)
return;
int mid = (l + r) >> 1;
build(k << 1, l, mid);
build(k << 1 | 1, mid + 1, r);
}
void update(int k) {
t[k].data = t[k << 1 | 1].data ? t[k << 1 | 1].data : t[k << 1].data;
}
void modify(int k, int pos, int val) {
init;
if (l == r) {
if (deep[val] > deep[t[k].data])
t[k].data = val;
return;
}
if (pos <= mid)
modify(k << 1, pos, val);
else
modify(k << 1 | 1, pos, val);
update(k);
}
int query(int k, int x, int y) {
init;
if (x <= l && r <= y) {
return t[k].data;
}
int ans = 0;
if (x <= mid) {
int t = query(k << 1, x, y);
if (deep[t] > deep[ans])
ans = t;
}
if (y > mid) {
int t = query(k << 1 | 1, x, y);
if (deep[t] > deep[ans])
ans = t;
}
return ans;
}
void ask(int x, int f) {
int ans = 0;
while (belong[x] != belong[f]) {
int t = query(1, bl[belong[x]], bl[x]);
ans = t ? t : 0;
if (ans)
break;
x = fa[belong[x]];
}
int t = query(1, bl[belong[x]], bl[x]);
ans = t ? t : 0;
printf("%d\n", ans);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input", "r", stdin);
#endif
scanf("%d %d", &n, &Q);
deep[0] = -1;
for (int i = 1; i < n; i++) {
int x, y;
scanf("%d %d", &x, &y);
add_edge(x, y);
add_edge(y, x);
}
dfs1(1);
dfs2(1, 1);
build(1, 1, dfn);
while (Q--) {
char op[5];
scanf("%s", op);
if (op[0] == 'Q') {
int x;
scanf("%d", &x);
ask(x, 1);
} else {
int x;
scanf("%d", &x);
tag[x] = 1;
modify(1, bl[x], x);
}
}
}
[bzoj4551][Tjoi2016&Heoi2016]树-树链剖分的更多相关文章
- BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树
题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...
- [BZOJ4551][TJOI2016&&HEOI2016]树(并查集)
4551: [Tjoi2016&Heoi2016]树 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1746 Solved: 800[Sub ...
- bzoj4553 [Tjoi2016&Heoi2016]序列 树状数组(区间最大值)+cqd
[Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1006 Solved: 464[Submit][ ...
- 线段树&数链剖分
傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...
- BZOJ4551 Tjoi2016&Heoi2016树(离线+并查集)
似乎是弱化的qtree3.树剖什么的非常无脑.考虑离线.并查集维护每个点的最近打标记祖先,倒序处理,删除标记时将其与父亲合并即可. #include<iostream> #include& ...
- BZOJ4551——[Tjoi2016&Heoi2016]树
1.题意: 给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个 结点,可以打多次标记.)2. 询问操作:询问某个 ...
- [bzoj4551][Tjoi2016][Heoi2016]树
Description 在2016年,佳媛姐姐刚刚学习了树,非常开心. 现在她想解决这样一个问题:给定一颗有根树(根为1),有以下两种操作: 1. 标记操作:对某个结点打上标记(在最开始,只有结点1有 ...
- BZOJ4551: [Tjoi2016&Heoi2016]树
Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标 ...
- BZOJ4553: [Tjoi2016&Heoi2016]序列 树套树优化DP
把pos[i]上出现的平常值定义为nor[i]最大值定义为max[i]最小值定义为min[i],那么我们发现在两个值,i(前),j(后),当且仅当max[i]<=nor[j],nor[i]< ...
随机推荐
- javascript如何自动去除所有空格?
1.jquery自带了trim方法: $.trim(" abc ") // abc 2.自己写方法: function trim(str) { return str.repl ...
- MyBatis动态传入表名,字段名参数的解决办法
原文:http://blog.csdn.net/xichenguan/article/details/50393748 要实现动态传入表名.列名,需要做如下修改 添加属性statementType=& ...
- CSS基础--常用样式
一.背景相关 背景颜色 background-color :颜色名称/rgb值/十六进制值 背景图片 background-image :url('') 背景图片平铺方式 background-rep ...
- oracle01
01-基本的查询语句 A:一些命令 sqlplus sys/sys@192.168.22.220:1521/orcl as sysdba; conn scott/123456@192.168.22.2 ...
- visual studio 中无法删除项目或者文件
vs 2012添加新项目或者类库后,里边的class文件,我不想要,就把它删除.但是删除的时候,报如下图的错误,我删除新建的项目或类库的时候,也报类似的错误,怎么解决? window系统是新安装的.也 ...
- linux_samba服务安装
什么是samba服务? 用于Windows和linux系统之间实现共享文件的目的服务 如何配置其服务? Linux端: 搭建服务 1. 安装samba yum install -y samba 2. ...
- js_1_变量类型
js中有哪些变量类型? 数字(包括int和float),字符串,数组(字典,js没有字典类型,把字典看成一个对象) 如何把字符转成数字呢? obj.parseInt() // 转化成 ...
- springmvc图片上传(兼容ie8以上,实时预览)
html代码: <form id="uploadform" method="post" enctype="multipart/form-data ...
- SQL 优化经验总结34条(转)
(1) 选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE 的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最 ...
- 错误:Invalid action class configuration that references an unknown class named [XXX]的解决
问题: 用http的方式直接调用类,执行完毕后报错误信息Invalid action class configuration that references an unknown class name ...