[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=4551

[算法]

树链剖分

时间复杂度 : O(QlogN)

[代码]

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010 struct Node
{
int l , r;
bool flg;
} Tree[MAXN << ];
struct edge
{
int to , nxt;
} e[MAXN << ]; int n , q , timer , tot;
int size[MAXN],top[MAXN],dfn[MAXN],head[MAXN],son[MAXN],father[MAXN],rev[MAXN]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void addedge(int u,int v)
{
tot++;
e[tot] = (edge){v,head[u]};
head[u] = tot;
}
inline void dfs1(int u)
{
size[u] = ;
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v == father[u]) continue;
father[v] = u;
dfs1(v);
size[u] += size[v];
if (size[v] > size[son[u]]) son[u] = v;
}
}
inline void dfs2(int u,int tp)
{
dfn[u] = ++timer;
rev[timer] = u;
top[u] = tp;
if (son[u]) dfs2(son[u],tp);
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v != son[u] && v != father[u]) dfs2(v,v);
}
}
inline void update(int index)
{
Tree[index].flg = Tree[index << ].flg | Tree[index << | ].flg;
}
inline void build(int index,int l,int r)
{
Tree[index].l = l;
Tree[index].r = r;
Tree[index].flg = false;
if (l == r)
{
if (l == ) Tree[index].flg = true;
return;
}
int mid = (l + r) >> ;
build(index << ,l,mid);
build(index << | ,mid + ,r);
update(index);
}
inline void modify(int index,int pos)
{
if (Tree[index].l == Tree[index].r)
{
Tree[index].flg = true;
return;
}
int mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= pos) modify(index << ,pos);
else modify(index << | ,pos);
update(index);
}
inline int query(int index,int l,int r)
{
if (!Tree[index].flg) return ;
if (Tree[index].l == Tree[index].r) return l;
int mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= r) return query(index << ,l,r);
else if (mid + <= l) return query(index << | ,l,r);
else
{
int tmp = query(index << | ,mid + ,r);
if (tmp == ) tmp = query(index << ,l,mid);
return tmp;
}
} int main()
{ scanf("%d%d",&n,&q);
for (int i = ; i < n; i++)
{
int u , v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
dfs1();
dfs2(,);
build(,,n);
while (q--)
{
char op[];
int x;
scanf("%s%d",&op,&x);
if (op[] == 'Q')
{
int tx = top[x] , pos = ;
while (true)
{
pos = query(,dfn[tx],dfn[x]);
if (pos != ) break;
x = father[tx]; tx = top[x];
}
printf("%d\n",rev[pos]);
} else modify(,dfn[x]);
} return ; }

[Tjoi2016&Heoi2016] 树的更多相关文章

  1. BZOJ 4551: [Tjoi2016&Heoi2016]树

    4551: [Tjoi2016&Heoi2016]树 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 748  Solved: 394[Subm ...

  2. BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树

    BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...

  3. [BZOJ4551][TJOI2016&&HEOI2016]树(并查集)

    4551: [Tjoi2016&Heoi2016]树 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1746  Solved: 800[Sub ...

  4. 【BZOJ4551】[Tjoi2016&Heoi2016]树 并查集

    [BZOJ4551][Tjoi2016&Heoi2016]树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下两 ...

  5. BZOJ4551——[Tjoi2016&Heoi2016]树

    1.题意: 给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个 结点,可以打多次标记.)2. 询问操作:询问某个 ...

  6. [bzoj4551][Tjoi2016][Heoi2016]树

    Description 在2016年,佳媛姐姐刚刚学习了树,非常开心. 现在她想解决这样一个问题:给定一颗有根树(根为1),有以下两种操作: 1. 标记操作:对某个结点打上标记(在最开始,只有结点1有 ...

  7. BZOJ4551: [Tjoi2016&Heoi2016]树

    Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标 ...

  8. [bzoj4551][Tjoi2016&Heoi2016]树-树链剖分

    Brief Description 给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个 结点,可以打多次标记.) ...

  9. BZOJ 4551[Tjoi2016&Heoi2016]树(树链剖分+二分)

    Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记 ...

  10. BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树

    题目描述 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均 ...

随机推荐

  1. hihoCoder#1196 : 高斯消元·二(开关灯问题)

    传送门 高斯消元解异或方程组 小Ho在游戏板上忙碌了30分钟,任然没有办法完成,于是他只好求助于小Hi. 小Ho:小Hi,这次又该怎么办呢? 小Hi:让我们来分析一下吧. 首先对于每一个格子的状态,可 ...

  2. Codevs 2756 树上的路径

    2756 树上的路径  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master     题目描述 Description 给出一棵树,求出最小的k,使得,且在树中存在 ...

  3. 【POJ1185】炮兵阵地(状压DP)

    题意: 思路:状压DP经典题 可以预处理下每一行内合法的状态,发现很少 所以转移时可以使用状态的编号而不是状态本身 DP时记录前两行状态的编号进行转移和判断 #include<cstdio> ...

  4. ***ps -ef |grep 输出的具体含义是什么?

    Q: 比如:[root@localhost ~]# ps -ef | grep ApacheJetspeedroot 18887 18828 0 08:09 pts/0 00:00:00 grep A ...

  5. hdu - 5128 The E-pang Palace(枚举+计算几何)

    http://acm.hdu.edu.cn/showproblem.php?pid=5128 给出n个点,求n个点组成两个矩形的最大面积. 矩形必须平行x轴,并且不能相交,但是小矩形在大矩形内部是可以 ...

  6. 某考试 T1 至危警告

    题目大意就是: 设f(x)为x各个位数字之和,求x属于[0,k]且b * f(x)^a + c = x的x个数并升序输出. (a<=5  .  b,c,<=10^4  .   k<= ...

  7. vue2.0单元测试(一)

    1.在vue init webpack XXX创建项目的时候 最后2步选择YES就启动了vue单元测试开始了   2.测试是使用karma+mocha框架来实现的方法,安装虚拟浏览器模块Phantom ...

  8. Apache 处理svg工具包Apache(tm) Batik SVG Toolkit

    Apache™ Batik SVG Toolkit¶ Overview¶ Batik is a Java-based toolkit for applications or applets that ...

  9. linux字符驱动之poll机制按键驱动

    在上一节中,我们讲解了如何自动创建设备节点,实现一个中断方式的按键驱动.虽然中断式的驱动,效率是蛮高的,但是大家有没有发现,应用程序的死循环里的读函数是一直在读的:在实际的应用场所里,有没有那么一种情 ...

  10. 【转】C++函数的重载、覆盖和隐藏区别

    网上看到的关于C++函数的重载.覆盖和隐藏区别的回答,如下(其内容来源于C++面试宝典中一道题目): a.成员函数被重载的特征:(1)相同的范围(在同一个类中):(2)函数名字相同:(3)参数不同:( ...