题目

在2016年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为1),有以下

两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个

结点,可以打多次标记。)2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖

先)你能帮帮他吗?

分析

此题有很多种方法

暴力+并查集

转了别人的

考虑离线处理。

我们将所有的操作倒序处理,利用并查集进行维护。对于一个修改操

作(即失去标记),相当于将这一联通块块与它父亲的联通块合并。对于

一个查询操作,直接查询所在的块的父亲即可。

实现中有些细节需要注意,比如每个点可能会被标记多次,所以要以

最早的被标记时间做为“失去标记”的时间。

时间复杂度为O(n + qα(n))

DFN序+线段树

首先搞一遍dfn序,

接着发现,在用一棵子树中,dfn序都是相邻的。

好了,线段树修改查询。

树链剖分

单独修改、查询1到num的路径。

裸题一枚。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
const int mo=1000000007;
const int N=100005;
using namespace std;
int tree[N*6],top[N],d[N],size[N],deep[N],son[N],fa[N],n,m,tot,ans;
int last[N*2],next[N*2],to[N*2],bef[N],aft[N];
void bj(int x,int y)
{
next[++tot]=last[x];
last[x]=tot;
to[tot]=y;
}
void dg(int x,int y)
{
size[x]=1;
int mx=0;
for(int i=last[x];i;i=next[i])
{
int j=to[i];
if(j!=y)
{
deep[j]=deep[x]+1;
fa[j]=x;
dg(j,x);
size[x]+=size[j];
if(size[j]>mx)
{
mx=size[j];
son[x]=j;
}
}
}
}
int dg1(int x,int y)
{
d[++tot]=x;
aft[x]=tot;
bef[tot]=x;
if(!top[x])
top[x]=x;
if(son[x])
{
top[son[x]]=top[x];
dg1(son[x],x);
}
for(int i=last[x];i;i=next[i])
{
int j=to[i];
if(j!=y && j!=son[x])
{
dg1(j,x);
}
}
}
int put(int v,int l,int r,int x)
{
if(l==r)
{
tree[v]=bef[x];
return 0;
}
int mid=(l+r)/2;
if(x<=mid)
{
put(v*2,l,mid,x);
}
else
put(v*2+1,mid+1,r,x);
tree[v]=deep[tree[v*2]]>deep[tree[v*2+1]]?tree[v*2]:tree[v*2+1];
}
int find(int v,int l,int r,int x,int y)
{
if(l==x && r==y)
{
ans=deep[ans]>deep[tree[v]]?ans:tree[v];
return 0;
}
int mid=(l+r)/2;
if(y<=mid)
{
find(v*2,l,mid,x,y);
}
else
if(mid<x)
{
find(v*2+1,mid+1,r,x,y);
}
else
{
find(v*2,l,mid,x,mid);
find(v*2+1,mid+1,r,mid+1,y);
}
tree[v]=deep[tree[v*2]]>deep[tree[v*2+1]]?tree[v*2]:tree[v*2+1];
}
int main()
{
freopen("4604.in","r",stdin);
freopen("4604.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n-1;i++)
{
int x,y;
scanf("%d%d",&x,&y);
bj(x,y);
bj(y,x);
}
deep[1]=1;
dg(1,0);
top[1]=1;
tot=0;
dg1(1,0);
put(1,1,n,aft[1]);
scanf("\n");
for(int i=1;i<=m;i++)
{
int c;
int x,y;
c=getchar();
while((c!='Q')&&(c!='C'))c=getchar();
scanf("%d\n",&x);
if(c=='C')
{
put(1,1,n,aft[x]);
}
else
{
ans=0;
while(top[x]!=top[1])
{
find(1,1,n,aft[top[x]],aft[x]);
x=fa[top[x]];
}
find(1,1,n,aft[1],aft[x]);
printf("%d\n",ans);
}
}
}

【bzoj4551】【NOIP2016模拟7.11】树的更多相关文章

  1. NOIP2016模拟赛三 Problem B: 神奇的树

    题面 Description 有一棵神奇的树.这棵树有N个节点,在每个节点上都有宝藏,每个宝藏价值V[i]金币:对于每条边,每经过一次都要花费C[i]金币. 值得注意的是,每个宝藏只能领取一次(也可以 ...

  2. JZOJ 4611. 【NOI2016模拟7.11】接水问题 (贪心+A*+可持久化线段树)

    Description: https://gmoj.net/senior/#main/show/4611 题解: 先把A从大到小排序,最小的由排序不等式显然. 考虑类似第k短路的A*的做法. 定义状态 ...

  3. 「考试」noip模拟9,11,13

    9.1 辣鸡 可以把答案分成 每个矩形内部连线 和 矩形之间的连线 两部分 前半部分即为\(2(w-1)(h-1)\),后半部分可以模拟求(就是讨论四种相邻的情况) 如果\(n^2\)选择暴力模拟是有 ...

  4. vue 模拟下拉树

    // 使用vue 做表格部分其他部分暂不修改 var app = new Vue({ el: "#freightTbl", watch: { //监听表格数据的变化[使用 watc ...

  5. [转载]如何在C++03中模拟C++11的右值引用std::move特性

    本文摘自: http://adamcavendish.is-programmer.com/posts/38190.htm 引言 众所周知,C++11 的新特性中有一个非常重要的特性,那就是 rvalu ...

  6. 串门赛: NOIP2016模拟赛——By Marvolo 丢脸记

    前几天liu_runda来机房颓废,顺便扔给我们一个网址,说这上面有模拟赛,让我们感兴趣的去打一打.一开始还是没打算去看一下的,但是听std说好多人都打,想了一下,还是打一打吧,打着玩,然后就丢脸了. ...

  7. 6424. 【NOIP2019模拟2019.11.13】我的订书机之恋

    题目描述 Description Input Output Sample Input 见下载 Sample Output 见下载 Data Constraint 题解 lj题卡线段树 求出每个右端点往 ...

  8. [CSP-S模拟测试]:砍树(数学+模拟)

    题目传送门(内部题1) 输入格式 第一行两个整数$n$,$k$,代表树苗的数量和最大看书的总长度.第二行n个整数$a_i$,代表林先森希望每棵树苗的最终高度. 输出格式 一行一个整数,代表最大可能的d ...

  9. 2019.8.1 NOIP模拟测试11 反思总结

    延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...

随机推荐

  1. Quaternions 四元数

    四元数是一个乱七八糟得到东西还没搞懂搞懂后再补 先添加unity API transform.rotation 是Quaternionlei类并非Vector3向量 不能进行直接转化 那如何将Vect ...

  2. Apache配置文件介绍

    一.配置文件存放位置 apache配置文件名为httpd.conf 1.yum安装 yum安装后,apache配置文件httpd.conf存放在目录/etc/httpd/conf下 2.源码编译安装 ...

  3. 中国MOOC_零基础学Java语言_第6周 使用对象_1单词长度

    第6周编程题 查看帮助 返回   第6周编程题 依照学术诚信条款,我保证此作业是本人独立完成的. 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截 ...

  4. 一个ETF基金经理的心路历程

    简介: 鹏华沪深300ETF拟任基金经理崔俊杰先生,金融工程专业管理学硕士,5年证券基金从业经验.2008年7月加盟鹏华基金管理有限公司,历任产品规划部产品设计师.量化投资部量化研究员,先后从事产品设 ...

  5. mysql数据库delete数据时不支持表别名!!!

    mysql数据库delete数据时不支持表别名!!! mysql delete时候 提示语法错误!如下sql: 去掉 表别名的时候: 正确的写法例如: DELETE FROM COMMENTS_REP ...

  6. Jmeter 后置处理器--jp@gc - JSON/YAML Path Extractor & JSON Extractor

    后置处理器--jp@gc - JSON/YAML Path Extractor 1.需要下载插件,地址: 解压后把对应jar包放置对应的lib和lib/ext目录下,重启Jmeter: 2.在需要提取 ...

  7. Linux 项目上线流程

    命令行样式修改 1 打开配置文件vim /etc/bashrc2 添加配置信息PS1="\[\e[37;40m\][\[\e[32;1m\]\u\[\e[37;40m\]@\h \[\e[3 ...

  8. docker--搭建docker swarm集群

    10 搭建docker swarm集群 10.1 swarm 介绍 Swarm这个项目名称特别贴切.在Wiki的解释中,Swarm behavior是指动物的群集行 为.比如我们常见的蜂群,鱼群,秋天 ...

  9. VS2013启动 外接程序VMDebugger未能加载或导致了异常

    故障现象:打开Visual Studio 2010后弹出错误框,外接程序VMDebugger未能加载或导致了异常,是否希望移除该外接程序,错误号:80004005.系统版本:WIN10 64位专业版, ...

  10. Dubbo原理学习

    Dubbo源码及原理学习 阿里中间件团队博客 Dubbo官网 Dubbo源码解析 Dubbo源码解析-掘金 Dubbo源码解析-赵计刚 Dubbo系列 源码总结+最近感悟