[题目链接]

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. PTA 02-线性结构2 一元多项式的乘法与加法运算 (20分)

    原题地址 https://pta.patest.cn/pta/test/15/exam/4/question/710 5-2 一元多项式的乘法与加法运算   (20分) 设计函数分别求两个一元多项式的 ...

  2. visual studio用"查找替换"来删掉源代码中所有//方式的纯注释和空行

    visual studio用"查找替换"来删掉源代码中所有//方式的纯注释和空行 注意:包括/// <summary>这样的XML注释也都删掉了. 步骤1/2(删除注释 ...

  3. hdu2157:How many ways??

    n<=20个点m<=100条边有向图不带权,t个询问问Ai到Bi的经过k<=20条边方案数多少. f[i][j]--i到j的方案数,,初始化成初邻接矩阵,这样做一次就得到2条路最短路 ...

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

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

  5. 编译.net .net Core程序 代码,仅做备份

    //创建一个ProcessStartInfo对象 使用系统shell 指定命令和参数 设置标准输出 //编译.net core项目 var psi = new ProcessStartInfo(&qu ...

  6. hotswapagent——热更新代码而无需重启生产环境

    http://blog.csdn.net/littleschemer/article/details/51645722

  7. 打开input输入的时候,css中position:absolute/fixed定位的时候,定位元素上移问题解决

    1.异常代码 <style> .box{ min-height: 100vh; width: 100%; position: relative; } .position{ position ...

  8. java比较两个日期大小

    方法一 /** * 比较两个日期之间的大小 * * @param d1 * @param d2 * @return 前者大于后者返回true 反之false */ public boolean com ...

  9. HDU 4786 Fibonacci Tree(生成树,YY乱搞)

    http://acm.hdu.edu.cn/showproblem.php? pid=4786 Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others ...

  10. 火狐浏览器Firefox 如何下载网页的SWF视频,硅谷动力的网站视频怎么下载

    1 使用火狐浏览器查看到底视频在哪里,我随便开了一段视频,发现这个SWF(外框套了一个Control.swf,内层才是真实的09-class.swf)   2 我们从下面这一段代码中进行分析 < ...