当前位置: 首页 > news >正文

【BZOJ 4551】【TJOI2016】【HEOI2016】树

题目描述

给定一棵有根树(根为 $1$),有以下两种操作:
$1.$ 标记操作:对某个结点打上标记(在最开始,只有结点$1$有标记,其他结点均无标记,而且对于某个结点,可以打多次标记。)
$2.$ 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖先)。

输入格式

输入第一行两个正整数 $N$ 和 $Q$ 分别表示节点个数和操作次数
接下来 $N-1$ 行,每行两个正整数 $u,v$ ($1\leq$$u,v$$\leq$$n$) 表示 $u$ 到$ v$ 有一条有向边
接下来 $Q$ 行,$“ C ”$时表示这是一个标记操作,为$“ Q ”$时表示这是一个询问操作。

输出格式

 对于每一个询问操作,输出一个正整数,表示结果。 

输入样例

5 5
1 2
1 3
2 4
2 5
Q 2
C 2
Q 2
Q 5
Q 3

输出样例

1
2
2
1

数据范围

 $1 \leq  N,Q \leq 10^5$

 

题解

初始时打好所有标记,逆序处理,用并查集维护,当遇到一个询问操作时,把标记 $-1$ ,若此时标记变为 $0$ ,则将该点与父亲节点合并。

 

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define N 1500005
#define depth 32
using namespace std;
int n,q,tot;
struct hh
{int to,next;}e[N<<1];
int fa[N],dep[N],col[N],last[N],f[N],opt[N],x[N],ans[N];
void add(int a,int b)
{
    e[++tot].to=b;
    e[tot].next=last[a];
    last[a]=tot;
}
void dfs(int now)
{
    int i;
    for(i=last[now];i;i=e[i].next)
        if(!dep[e[i].to])
        {
            dep[e[i].to]=dep[now]+1;
            fa[e[i].to]=now; 
            dfs(e[i].to);
        }
}
int read()
{
    int ret=0;char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)){
        ret=(ret<<1)+(ret<<3)+c-'0';
        c=getchar();
    }
    return ret;
}
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
int main()
{
    int i,j,u,v,fx,fy;
    char flag;
    n=read();q=read();
    for(i=1;i<=n-1;i++)
    {
        u=read();v=read();
        add(u,v); add(v,u);
    }
    dfs(1);
    for(i=1;i<=q;i++)
    {
        scanf("\n%c",&flag);
        if(flag=='C') opt[i]=1;
        else opt[i]=2;
        x[i]=read();
    }
    dep[1]=1;col[1]=1;
    for(i=1;i<=q;i++)
        if(opt[i]==1) col[x[i]]++;
    for(i=1;i<=n;i++) f[i]=i;
    for(i=2;i<=n;i++)
        if(!col[i]) f[find(i)]=find(fa[i]);
    for(i=q;i>=1;i--)
        if(opt[i]==2) ans[++ans[0]]=find(x[i]);
        else
        {
            col[x[i]]--;
            if(!col[x[i]]) f[find(x[i])]=find(fa[x[i]]);
        }
    for(i=ans[0];i>=1;i--)
        printf("%d\n",ans[i]);
    return 0;
}
View Code

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/yljiang/p/9637114.html

相关文章:

  • oracle多表查询-自连接
  • swiper 点击切换,拖动切换后继续自动轮播
  • Python 之 文件操作
  • Java 8 方法引用
  • Docker-基本命令
  • jenkins发送html测试报告
  • 项目配置 xml文件时 报错提示(The reference to entity useSSL must end with the ';' delimiter.)...
  • Golang操作结构体、Map转化为JSON
  • 犯得错误QAQ
  • Python基础装饰器的基本原理
  • 在vue中使用animate.css
  • 集中绕组和分布绕组
  • redis pubsub
  • 【BZOJ4006】管道连接(动态规划,斯坦纳树)
  • 9-18 一次编程面试
  • [PHP内核探索]PHP中的哈希表
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • Babel配置的不完全指南
  • ES6系列(二)变量的解构赋值
  • Javascript弹出层-初探
  • java中的hashCode
  • JDK9: 集成 Jshell 和 Maven 项目.
  • js面向对象
  • Laravel 菜鸟晋级之路
  • Python十分钟制作属于你自己的个性logo
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • storm drpc实例
  • vuex 学习笔记 01
  • vue数据传递--我有特殊的实现技巧
  • Vue小说阅读器(仿追书神器)
  • 闭包--闭包作用之保存(一)
  • 动态规划入门(以爬楼梯为例)
  • 后端_MYSQL
  • 利用jquery编写加法运算验证码
  • 前端之Sass/Scss实战笔记
  • 区块链分支循环
  • 温故知新之javascript面向对象
  • 怎样选择前端框架
  • Spring第一个helloWorld
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 如何用纯 CSS 创作一个货车 loader
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​什么是bug?bug的源头在哪里?
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • !$boo在php中什么意思,php前戏
  • #Ubuntu(修改root信息)
  • (1)SpringCloud 整合Python
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (二)斐波那契Fabonacci函数
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (十)c52学习之旅-定时器实验