BZOJ 4551树题解
好吧,洛谷的数据比较水暴力就可以过。。。。(而且跑到飞快)
不过(BZ水不过去)还是讲讲正规的做法。
其实一眼可以看出可以树剖,但是,码起来有点麻烦。
其实有一种更简单的离线做法。
我们很容易联想到并查集,利用并查集来维护各个点的最近的标记的祖先,但是加入标记后会产生分离的操作,这对并查集来说不好操作
所以我们先将所有的询问读入,将所有的标记都打上去。
从后往前处理。如果有一个点的标记变为了0,就将该点与它的父亲合并。
不知为何,在luogu上跑的比暴力要慢一点。。。。
# include<iostream>
# include<cstdio>
# include<cmath>
# include<cstring>
# include<algorithm>
using namespace std;
const int mn = 100005;
int n,m;
int c[mn],a[mn],fa[mn],ans[mn];
char opt[mn];
struct edge{int next,to;}e[mn*2];
int head[mn],edge_max;
inline void add_edge(int x,int y)
{
e[++edge_max]=(edge){head[x],y};head[x]=edge_max;
}
int f[mn];//并查集的fa数组
int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
}
void dfs(int x)
{
f[x]=c[x]?x:fa[x];
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to;
if (y!=fa[x]) fa[y]=x,dfs(y);
}
}
int main()
{
int x,y;
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add_edge(x,y);
add_edge(y,x);
}
c[1]=1;
for(int i=1;i<=m;i++)
{
scanf(" %c%d",&opt[i],&a[i]);
if (opt[i]=='C') c[a[i]]++;
}
dfs(1);
for(int i=m;i>=1;i--)
{
if (opt[i]=='C')
{
c[a[i]]--;
if(!c[a[i]])
f[a[i]]=fa[a[i]];
}
else ans[i]=find(a[i]);
}
for(int i=1;i<=m;i++)
{
if(ans[i])
printf("%d\n",ans[i]);
}
return 0;
}
BZOJ 4551树题解的更多相关文章
- BZOJ 4551 树
线段树+标记永久化. #include<iostream> #include<cstdio> #include<cstring> #include<algor ...
- BZOJ 1179 Atm 题解
BZOJ 1179 Atm 题解 SPFA Algorithm Tarjan Algorithm Description Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来 ...
- Vijos1448校门外的树 题解
Vijos1448校门外的树 题解 描述: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现 ...
- BZOJ 4551: [Tjoi2016&Heoi2016]树
4551: [Tjoi2016&Heoi2016]树 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 748 Solved: 394[Subm ...
- 【BZOJ 4551】【TJOI2016】【HEOI2016】树
http://www.lydsy.com/JudgeOnline/problem.php?id=4551 题目描述 给定一棵有根树(根为 1),有以下两种操作:1. 标记操作:对某个结点打上标记(在最 ...
- BZOJ 4551[Tjoi2016&Heoi2016]树(树链剖分+二分)
Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记 ...
- BZOJ 4551 [Tjoi2016&Heoi2016]树 ——并查集
树剖显然可以做. 然而有一种更神奇的方法,并查集+时光倒流. 每个节点指向它上面最近的标记节点,标记节点指向自己,然后删除标记,就可以用并查集查询了. #include <map> #in ...
- BZOJ 4551: [Tjoi2016&Heoi2016]树 并查集(&&图论?)
反向操作,先把所有的标记都打上(记得统计标记的数目),然后依次撤销,合并到自己的上一个点pre,即fa[u]=getf(pre[u]) #include<cstdio> #include& ...
- bzoj 4551: [Tjoi2016&Heoi2016]树【并查集】
看起来像是并查集,但是是拆集合,考虑时间倒流,先把标记都打上,然后把并查集做出来 每次到一个修改点就把这个点的计数s[u]--,当这个s为0时就把这个点和他的父亲合并(因为可能有多次标记) #incl ...
随机推荐
- tensorflow/model下的各个参数的理解
首先,这个对应的proto就是 然后config里面的image_resizer等等 就是proto里面的image_resizer 等等,对应的参数可以在proto里面寻找解释和默认值以及类型 再比 ...
- java 中Vector的使用详解
Vector 可实现自动增长的对象数组. java.util.vector提供了向量类(vector)以实现类似动态数组的功能.在Java语言中没有指针的概念,但如果正确灵活地使用指针又确实可以大大提 ...
- 2019-3-8-win10-uwp-一张图说明水平对齐和垂直对齐
title author date CreateTime categories win10 uwp 一张图说明水平对齐和垂直对齐 lindexi 2019-03-08 10:45:40 +0800 2 ...
- TZOJ 4292 Count the Trees(树hash)
描述 A binary tree is a tree data structure in which each node has at most two child nodes, usually di ...
- CF538G (套路题)
CF538G 题目大意 你有一个长度为\(l\)的指令序列,每个指令为向上,向下,向左,向右中的一种. 机器人会循环执行该序列,即,执行完第\(l\)个指令后,就会重新开始执行第一个指令. 现在,给你 ...
- Leetcode459.Repeated Substring Pattern重复的子字符串
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成.给定的字符串只含有小写英文字母,并且长度不超过10000. 示例 1: 输入: "abab" 输出: True 解释 ...
- Django项目:CRM(客户关系管理系统)--45--37PerfectCRM实现King_admin添加用户时密码加密
#views # ————————02PerfectCRM创建ADMIN页面———————— from django.shortcuts import render # ————————04Perfe ...
- androidstudio实现增量更新步骤
本文demo和参考例子参考-传送 门:http://blog.csdn.net/duguang77/article/details/17676797 一.增量更新优点:节省客户端和服务器端流量 增量 ...
- iview中table的render()函数
Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更接 ...
- angular和vue的对比学习之路
vue-ng 打开vue的中文官网一段关于vue的描述 HTML 模板 + JSON 数据,再创建一个 Vue 实例,就这么简单. 那我么再看下angular中文网 AngularJS是为了克服HTM ...