Description

给出N个点的一棵树(N-1条边),节点有白有黑,初始全为白

有两种操作:

0 i : 改变某点的颜色(原来是黑的变白,原来是白的变黑)

1 v : 询问1到v的路径上的第一个黑点,若无,输出-1

Input

第一行 N,Q,表示N个点和Q个操作

第二行到第N行N-1条无向边

再之后Q行,每行一个操作"0 i" 或者"1 v" (1 ≤ i, v ≤ N).

Output

对每个1 v操作输出结果

很明显.树上区间问题,我们考虑树链剖分.

单点修改,我们就直接修改即可.

而对于这个询问操作,则有一些思维难度.(不是很难的

首先,遇到一个线段树上的节点.我们需要考虑其是否有黑点,如果有的话,我们优先选择左子树中的黑点,(可以保证是从\(1\)到\(v\)的第一个黑点)

具体实现起来不难,注意数组要开够.

复杂度\(O(能过)\)

代码

#include<cstdio>
#include<cctype>
#include<cstring>
#define R register
#define N 200008
using namespace std;
inline void in(int &x)
{
int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
}
int n,m,head[N],tot;
struct cod{int u,v;}edge[N<<2];
inline void add(int x,int y)
{
edge[++tot].u=head[x];
edge[tot].v=y;
head[x]=tot;
}
int f[N],depth[N],size[N],son[N];
void dfs1(int u,int fa)
{
f[u]=fa;depth[u]=depth[fa]+1;size[u]=1;
for(R int i=head[u];i;i=edge[i].u)
{
if(edge[i].v==fa)continue;
dfs1(edge[i].v,u);
size[u]+=size[edge[i].v];
if(son[u]==-1 or size[son[u]]<size[edge[i].v])
son[u]=edge[i].v;
}
}
int idx,dfn[N],fdfn[N],top[N];
void dfs2(int u,int t)
{
dfn[u]=++idx;fdfn[idx]=u;top[u]=t;
if(son[u]==-1)return;
dfs2(son[u],t);
for(R int i=head[u];i;i=edge[i].u)
{
if(dfn[edge[i].v])continue;
dfs2(edge[i].v,edge[i].v);
}
}
bool tr[N<<2];
int pos[N<<2];
#define ls o<<1
#define rs o<<1|1
inline void up(int o)
{
tr[o]=tr[ls] | tr[rs];
pos[o]= tr[ls] ? pos[ls]:(tr[rs]? pos[rs]:-1);
}
void change(int o,int l,int r,int poss)
{
if(l==r){tr[o]^=1;pos[o]=tr[o] ? fdfn[l]:-1; return;}
int mid=(l+r)>>1;
if(poss<=mid)change(ls,l,mid,poss);
else change(rs,mid+1,r,poss);
up(o);
}
int query(int o,int l,int r,int x,int y)
{
if(l>y or r<x)return -1;
if(x<=l and y>=r)return pos[o];
int mid=(l+r)>>1,le,ri;
le=query(ls,l,mid,x,y),ri=query(rs,mid+1,r,x,y);
return le==-1 ? ri:le;
}
inline int tquery(int x)
{
int ans=-1,p,fx=top[x];
while(fx!=1)
{
p=query(1,1,n,dfn[fx],dfn[x]);
ans=(p==-1? ans:p);
x=f[fx];fx=top[x];
}
p=query(1,1,n,1,dfn[x]);
ans=(p==-1 ? ans : p);
return ans;
}
int main()
{
in(n),in(m);
memset(son,-1,sizeof son);
memset(pos,-1,sizeof pos);
for(R int i=1,x,y;i<n;i++)
{
in(x),in(y);
add(x,y);add(y,x);
}
dfs1(1,0);
dfs2(1,1);
for(R int opt,x;m;m--)
{
in(opt);in(x);
if(opt==0)
change(1,1,n,dfn[x]);
else printf("%d\n",tquery(x));
}
}

树链剖分【p4116】Qtree3 - Query on a tree的更多相关文章

  1. 主席树+树链剖分——南昌邀请赛Distance on the tree

    学了差不多一星期的主席树+树链剖分,再来看这题发现其实是个板子题 一开始想复杂了,以为要用类似求树上第k大的树上差分思想来解决这道题,但其实树链上<=k的元素个数其实直接可以用树链剖分来求 具体 ...

  2. QTREE3 spoj 2798. Query on a tree again! 树链剖分+线段树

    Query on a tree again! 给出一棵树,树节点的颜色初始时为白色,有两种操作: 0.把节点x的颜色置反(黑变白,白变黑). 1.询问节点1到节点x的路径上第一个黑色节点的编号. 分析 ...

  3. 树链剖分&咕咕咕了好久好久的qtree3

    前言 显然qtree系列都是树链剖分辣 发现自己没有专门整理过树链剖分耶 辣么就把这篇博客魔改成树链剖分好辣(貌似除了树剖也没什么好写的) 正文 废话了辣么多终于开始了 一.树剖怎么写鸭 二.树剖有什 ...

  4. Qtree3题解(树链剖分(伪)+线段树+set)

    外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意: 很明显吧.. 题解: 我的做法十分的暴力:树链剖分(伪)+线段树+\(set\)... ...

  5. Qtree3题解(树链剖分+线段树+set)

    外话:最近洛谷加了好多好题啊...原题入口 这题好像是SPOJ的题,挺不错的.看没有题解还是来一篇... 题意 很易懂吧.. 题解 我的做法十分的暴力:树链剖分(伪)+线段树+ std :: set ...

  6. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

  7. SPOJ Query on a tree 树链剖分 水题

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  8. spoj 375 Query on a tree(树链剖分,线段树)

      Query on a tree Time Limit: 851MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Sub ...

  9. bzoj 3637: Query on a tree VI 树链剖分 && AC600

    3637: Query on a tree VI Time Limit: 8 Sec  Memory Limit: 1024 MBSubmit: 206  Solved: 38[Submit][Sta ...

随机推荐

  1. 【题解】[WC2006]水管局长

    感觉这题好强啊……本来以为能过,结果毫无疑问的被ge了一顿……在这里记录一下做的过程,也免得以后又忘记啦. 首先,我们应看出在这张图上,要让经过的水管最长的最短,就是要维护一棵动态的最小生成树.只是删 ...

  2. [Leetcode] first missing positve 缺失的第一个正数

    Given an unsorted integer array, find the first missing positive integer. For example,Given[1,2,0]re ...

  3. CF840C On the Bench 解题报告

    CF840C On the Bench 题意翻译 给定\(n\) \((1≤n≤300)\) 个数,求问有多少种排列方案使得任意两个相邻的数之积都不是完全平方数.由于方案数可能很大,输出方案数 \(m ...

  4. 如何写出规范的JavaScript代码

    作为一名开发人员(WEB前端JavaScript开发),不规范的开发不仅使日后代码维护变的困难,同时也不利于团队的合作,通常还会带来代码安全以及执行效率上的问题.本人在开发工作中就曾与不按规范来开发的 ...

  5. More on understanding sort_buffer_size

    There have been a few posts by Sheeri and Baron today on the MySQL sort_buffer_size variable. I want ...

  6. Codeforces 937.B Vile Grasshoppers

    B. Vile Grasshoppers time limit per test 1 second memory limit per test 256 megabytes input standard ...

  7. MySQL 配置文件及逻辑架构

    配置文件: linux:/etc/my.cnf              默认配置文件:/usr/share/mysql/my-default.cnf windows:my.ini 主要日志文件: 二 ...

  8. bzoj4900 [CTSC2017]密钥

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4900 [题解] 恭喜bzoj达到40页 考场由于傻逼基数排序写挂了而gg. 竟然忘了考试前一 ...

  9. mybatis注解动态sql

    @Insert("INSERT INTO user (name, age, gender, experience) VALUES (<a href="http://www.o ...

  10. zhudongfangyu.exe进程是360主动防御进程,用来监控电脑系统,防止电脑病毒出现并阻止病毒或木马的安全进程

    zhudongfangyu.exe进程是360主动防御进程,用来监控电脑系统,防止电脑病毒出现并阻止病毒或木马的安全进程