[HEOI2016/TJOI2016]树
时间:2021-08-11
本文章向大家介绍[HEOI2016/TJOI2016]树,主要包括[HEOI2016/TJOI2016]树使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
[HEOI2016/TJOI2016]树
这是一道树剖板子题,所以我们没什么讲的
题解
我们用线段树维护树剖序上的\(sum\)值,即为染色的数量的\(sum\),当\(sum=0\)时,从\(x\)节点向上爬树,当我们查询到这条链的\(sum>=1\)时二分答案即可。
#include<bits/stdc++.h>
using namespace std;
const int MN=1e5+100;
int n,q;
int head[MN],cnt;
struct node{
int nxt,to;
}e[MN<<1];
inline void add(int a,int b){e[++cnt].nxt=head[a],head[a]=cnt,e[cnt].to=b;}
int son[MN],siz[MN],fa[MN],dep[MN];
void dfs1(int now,int pre){
dep[now]=dep[pre]+1,fa[now]=pre,siz[now]=1;
for(int i=head[now];i;i=e[i].nxt){
int to=e[i].to;
if(to==pre)continue;
dfs1(to,now);
siz[now]+=siz[to];
if(siz[to]>siz[son[now]])son[now]=to;
}
}
int dfn[MN],top[MN],tot,name[MN];
void dfs2(int now,int tp){
top[now]=tp,dfn[now]=++tot,name[tot]=now;
if(son[now])dfs2(son[now],tp);
for(int i=head[now];i;i=e[i].nxt){
int to=e[i].to;
if(to==fa[now]||to==son[now])continue;
dfs2(to,to);
}
}
#define lc id<<1
#define rc id<<1|1
struct tree{
int l,r,sum;
}t[MN<<2];
void pushup(int id){
t[id].sum=t[lc].sum+t[rc].sum;
}
void build(int id,int l,int r){
t[id].l=l,t[id].r=r;
if(l==r)return;
int mid=(l+r)>>1;
build(lc,l,mid),build(rc,mid+1,r);
}
void change(int id,int k){
if(t[id].l==t[id].r&&t[id].l==k){
t[id].sum=1;
return;
}
int mid=(t[id].l+t[id].r)>>1;
if(k<=mid)change(lc,k);
else change(rc,k);
pushup(id);
}
int get_sum(int id,int l,int r){
if(t[id].l>=l&&t[id].r<=r)return t[id].sum;
int mid=(t[id].l+t[id].r)>>1,ans=0;
if(l<=mid)ans+=get_sum(lc,l,r);
if(r>=mid+1)ans+=get_sum(rc,l,r);
return ans;
}
int lower(int l,int r){
if(l==r)return name[l];
int mid=(l+r)>>1;
if(get_sum(1,mid+1,r))return lower(mid+1,r);
else return lower(l,mid);
}
int query(int x){
int ans=0;
while(!ans){
int sum=0;
sum=get_sum(1,dfn[top[x]],dfn[x]);
if(sum){
ans=lower(dfn[top[x]],dfn[x]);
}
else x=fa[top[x]];
}
return ans;
}
int main(){
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
scanf("%d%d",&n,&q);
for(int i=1,u,v;i<n;++i)scanf("%d%d",&u,&v),add(u,v),add(v,u);
dfs1(1,0);dfs2(1,1);build(1,1,n);change(1,dfn[1]);
int x;char s;
while(q--){
scanf("%s%d",&s,&x);
if(s=='Q')printf("%d\n",query(x));
else change(1,dfn[x]);
}
return 0;
}
原文地址:https://www.cnblogs.com/fanner-Blog/p/15129277.html
- Python进阶04 函数的参数对应
- Python进阶03 模块
- Python进阶02 文本文件的输入输出
- Python进阶01 词典
- 微信公布上线小程序游戏 腾讯应用宝安卓平台首发
- Python基础10 反过头来看看
- CCCF 微软沈向洋:理解自然语言:表述、对话和意境
- Linux进程基础
- Android Studio导入项目非常慢的解决办法
- Android开发中遇到的requestFeature() must be called before adding content异常
- Linux信号基础
- 剑指OFFER之合并有序链表(九度OJ1519)
- Android Studio快捷键每日一练(6)
- Linux文本流
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Go 数据存储篇(四):通过 Gob 包序列化二进制数据
- 引入 SB Admin 2 作为后台管理系统主题
- Laravel Jetstream是什么以及如何入门?
- Bash基础训练指南
- 基于NodeJS从零构建线上自动化打包工作流
- 如何实现H5可视化编辑器的实时预览和真机扫码预览功能
- LeetCode67|二分查找
- LeetCode66|二叉树的最小深度
- LeetCode65|回文链表
- LeetCode64|茴香豆???
- WEB安全学习二、注入工具 sqlmap的使用
- LeetCode63|香山碧云寺云碧山香
- LeetCode62|数组形式的整数加法
- LeetCode61|字符串相加
- LeetCode60|反转字符串