P6753 [BalticOI 2013 Day1] Ball Machine

题意

给你一个树,每次从根节点放一个求,如果其子节点有空这个球会向下滚,若有多个节点为空则找儿子中以子树内编号的最小值为优先级从小到大找第一个为空的位置滚。

有两种操作,第一种插入若干个球,输出最后一个球到的节点编号;第二种删除一个位置,此时若有可以向下滚的球那么这个球就会滚,输出有多少个球滚了。

保证数据合法。

思路

首先我们思考只有1操作的情况。

对于1操作,球加入的顺序为按照以子树内编号的最小值为优先级的后序遍历 dfs 序。我们得到了 40pts。

对于2操作,删掉一个球后答案一定是其所有祖先中有球的位置的个数。原因显然,因为删球前一定是最佳状态,即没有球能动,所以删掉这个球后只有其祖先会向下移动并且一定会向下移动。

发现祖先有球的段一定是连续的,于是我们就可以用倍增找到最浅的有球的祖先,并且顺便输出答案。

但是2操作后会把父亲节点删去。注意这时候删去的节点并非最后加入的点。而且下一次加入球时会找 dfs 序最小的。这时候我们就需要一些东西比如 stl 的 vector / priority_queue / set 进行维护了。

还有最最最重要的一点!对于操作1,我们是依次一个一个加入的,这样的时间复杂度为什么是正确的?

显然,因为每个2操作只会删1个点,所以我们最多会插入 n+q 个点。所以要什么重链剖分和线段树暴力就能过

实现

我用的是 vector 存储空节点来实现这个过程的。它的好处在于对于1操作删除是 \(O(1)\) 的。不过插入必须用 upper_bound 和 insert 。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
inline int read(){
int w=0,x=0;char c=getchar();
while(!isdigit(c))w|=c=='-',c=getchar();
while(isdigit(c))x=x*10+(c^48),c=getchar();
return w?-x:x;
}
namespace star
{
const int maxn=1e5+10;
int n,Q;
int fa[maxn][21],rt,dfn[maxn],tot,id[maxn],mn[maxn];
bool vis[maxn];
vector<int> q,G[maxn];
void dfs1(int x){
mn[x]=x;
for(int i=0;i<G[x].size();i++)
dfs1(G[x][i]),mn[x]=min(mn[x],mn[G[x][i]]);
}
inline bool cmp1(int a,int b){return mn[a]<mn[b];}
void dfs(int x){
for(int i=0;i<20;i++) fa[x][i+1]=fa[fa[x][i]][i];
sort(G[x].begin(),G[x].end(),cmp1);
for(int i=0;i<G[x].size();i++)
dfs(G[x][i]);
dfn[x]=++tot;
id[tot]=x;
}
inline bool cmp(int a,int b){return dfn[a]>dfn[b];}
inline void work(){
n=read(),Q=read();
for(int i=1;i<=n;i++){
if((fa[i][0]=read())==0) rt=i;
G[fa[i][0]].push_back(i);
}
dfs1(rt);
dfs(rt);q.resize(n),q.clear();
for(int i=n;i;i--) q.push_back(id[i]);
while(Q--)
if(read()==1){
int num=read();
while(--num)vis[q.back()]=1,q.pop_back();
printf("%d\n",q.back());
vis[q.back()]=1;q.pop_back();
}else{
int x=read();
if(!vis[x]){puts("0");continue;}//数据合法,好像没用
int f=x,ans=0;
for(int i=20;~i;i--) if(vis[fa[f][i]])f=fa[f][i],ans|=(1<<i);
vis[f]=0;
q.insert(upper_bound(q.begin(),q.end(),f,cmp),f);
printf("%d\n",ans);
}
}
}
signed main(){
star::work();
return 0;
}

其他

强烈吐槽洛谷的翻译!一直以为是以直接相连节点的编号大小为优先级,结果是子树内的最小值……建议大家看原题面。

P6753 [BalticOI 2013 Day1] Ball Machine的更多相关文章

  1. luoguP6754 [BalticOI 2013 Day1] Palindrome-Free Numbers

    目录 luoguP6754 [BalticOI 2013 Day1] Palindrome-Free Numbers 简述题意: Solution: Code luoguP6754 [BalticOI ...

  2. LOJ#2632. 「BalticOI 2011 Day1」打开灯泡 Switch the Lamp On

    题目描述 译自 BalticOI 2011 Day1 T3「Switch the Lamp On」有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会.有 N×M 个这样 ...

  3. P6739 [BalticOI 2014 Day1] Three Friends 题解

    目录 写在前面 Solution 何为字符串哈希(可跳过): Code 写在前面 P6739 [BalticOI 2014 Day1] Three Friends 听说这题可以用比较暴力的做法过,比如 ...

  4. NOIP 2013 day1

    tags: 模拟 快速幂 逆序对 树状数组 归并排序 最小生成树 lca 倍增 categories: 信息学竞赛 总结 tex live 2017.iso 转圈游戏 火柴排队 货车运输 转圈游戏 s ...

  5. P4675 [BalticOI 2016 day1]Park (并查集)

    题面 在 Byteland 的首都,有一个以围墙包裹的矩形公园,其中以圆形表示游客和树. 公园里有四个入口,分别在四个角落( 1 , 2 , 3 , 4 1, 2, 3, 4 1,2,3,4 分别对应 ...

  6. django开发个人简易Blog—nginx+uwsgin+django1.6+mysql 部署到CentOS6.5

    前面说完了此项目的创建及数据模型设计的过程.如果未看过,可以到这里查看,并且项目源码已经放大到github上,可以去这里下载. 代码也已经部署到sina sea上,地址为http://fengzhen ...

  7. 经过各种坑之后centos+ uwsgi + nginx +django 终于配好了

    https://pypi.python.org/pypi/setuptools#downloads https://www.python.org/ftp/python/ 开机 加入 uwsgi ngi ...

  8. LOJ 一本通一句话题解系列:

    第一部分 基础算法 第 1 章 贪心算法 1):「一本通 1.1 例 1」活动安排:按照结束时间排序,然后扫一遍就可以了. 2):「一本通 1.1 例 2」种树:首先要尽量的往区间重叠的部分种树,先按 ...

  9. 【搜索 ex-BFS】bzoj2346: [Baltic 2011]Lamp

    关于图中边权非零即一的宽度优先搜索 Description 译自 BalticOI 2011 Day1 T3「Switch the Lamp On」有一种正方形的电路元件,在它的两组相对顶点中,有一组 ...

随机推荐

  1. Salesforce LWC学习(三十四) 如何更改标准组件的相关属性信息

    本篇参考: https://www.cnblogs.com/zero-zyq/p/14548676.html https://www.lightningdesignsystem.com/platfor ...

  2. 深入理解java虚拟机笔记Chapter3-内存分配策略

    内存分配策略 新生代和老年代的 GC 操作 新生代 GC 操作:Minor GC 发生的非常频繁,速度较块. 老年代 GC 操作:Full GC / Major GC 经常伴随着至少一次的 Minor ...

  3. 狂神说redis笔记(二)

    四.三种特殊数据类型 Geospatial(地理位置) 使用经纬度定位地理坐标并用一个有序集合zset保存,所以zset命令也可以使用 geoadd key longitud(经度) latitude ...

  4. 03:CSS(01)

    内容概要 分组与嵌套 伪类选择器 伪元素选择器 选择器优先级 css属性相关(操作标签样式) 浮动 定位 模态框 透明度 内容详细 分组与嵌套 div,p,span { /*逗号表示并列关系*/ co ...

  5. css基本内容笔记(学习整理)

    一.css简介 1.什么是css 层叠样式表. 层叠:层层叠加,若果有冲突应用优先级高,不冲突的部分共同作用 样式表:就是css属性样式的集合: 2.作用 a.修饰html,使得html样式更好看 b ...

  6. Mysql权限管理以及sql数据备份

    权限管理和备份 用户管理 可视化管理 SQL命令操作 用户表:msql.user 同样就是对表的操作,就是对这张表的增删改查 -- 创建用户 create user kuangshen identfi ...

  7. SCP,SSH应用

  8. LVM与磁盘配额

    LVM与磁盘配额 目录 一.LVM概述 1.1.LVM 概述 1.2.LVM机制的基本概念 二.LVM 管理命令 2.1.主要命令 2.2.LVM命令详解 三.设置磁盘配额 3.1.磁盘配额的概述 3 ...

  9. 【进阶之路】深入理解Java虚拟机的类加载机制(长文)

    我们在参加面试的时候,经常被问到一些关于类加载机制的问题,也都会在面试之前准备的时候背好答案,但是我们是否有去深入了解什么是类加载机制呢?这段时间因为一些事情在家看了些书,这次就和大家分享一些关于Ja ...

  10. R语言读取文件

    1.R语言读取文件,文件类型为.txt 直接使用read.table()即可,若不知道当前的工作目录,可以使用函数getwd()来查看 2.R语言读取文件,文件类型为.xlsx 方法一:可以把excl ...