P6753 [BalticOI 2013 Day1] Ball Machine
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的更多相关文章
- luoguP6754 [BalticOI 2013 Day1] Palindrome-Free Numbers
目录 luoguP6754 [BalticOI 2013 Day1] Palindrome-Free Numbers 简述题意: Solution: Code luoguP6754 [BalticOI ...
- LOJ#2632. 「BalticOI 2011 Day1」打开灯泡 Switch the Lamp On
题目描述 译自 BalticOI 2011 Day1 T3「Switch the Lamp On」有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会.有 N×M 个这样 ...
- P6739 [BalticOI 2014 Day1] Three Friends 题解
目录 写在前面 Solution 何为字符串哈希(可跳过): Code 写在前面 P6739 [BalticOI 2014 Day1] Three Friends 听说这题可以用比较暴力的做法过,比如 ...
- NOIP 2013 day1
tags: 模拟 快速幂 逆序对 树状数组 归并排序 最小生成树 lca 倍增 categories: 信息学竞赛 总结 tex live 2017.iso 转圈游戏 火柴排队 货车运输 转圈游戏 s ...
- P4675 [BalticOI 2016 day1]Park (并查集)
题面 在 Byteland 的首都,有一个以围墙包裹的矩形公园,其中以圆形表示游客和树. 公园里有四个入口,分别在四个角落( 1 , 2 , 3 , 4 1, 2, 3, 4 1,2,3,4 分别对应 ...
- django开发个人简易Blog—nginx+uwsgin+django1.6+mysql 部署到CentOS6.5
前面说完了此项目的创建及数据模型设计的过程.如果未看过,可以到这里查看,并且项目源码已经放大到github上,可以去这里下载. 代码也已经部署到sina sea上,地址为http://fengzhen ...
- 经过各种坑之后centos+ uwsgi + nginx +django 终于配好了
https://pypi.python.org/pypi/setuptools#downloads https://www.python.org/ftp/python/ 开机 加入 uwsgi ngi ...
- LOJ 一本通一句话题解系列:
第一部分 基础算法 第 1 章 贪心算法 1):「一本通 1.1 例 1」活动安排:按照结束时间排序,然后扫一遍就可以了. 2):「一本通 1.1 例 2」种树:首先要尽量的往区间重叠的部分种树,先按 ...
- 【搜索 ex-BFS】bzoj2346: [Baltic 2011]Lamp
关于图中边权非零即一的宽度优先搜索 Description 译自 BalticOI 2011 Day1 T3「Switch the Lamp On」有一种正方形的电路元件,在它的两组相对顶点中,有一组 ...
随机推荐
- ES6中的变量结构赋值
小编的上一篇文章更新了es6中关于变量定义的问题,这篇文章继续来一些实用的干货,关于数组.对象的赋值问题.特别是在前后端合作项目的时候,对后端数据的拆分,还有就是对于函数的默认值的惰性赋值问题.看完下 ...
- 如何让vscode C++ 终端不再显示调试启动信息
按照微软的官方文档(https://go.microsoft.com/fwlink/?LinkID=533484#vscode)配置好C++环境之后. 每次按F5都会在终端输出,但是会附加一串信息.例 ...
- 机械革命z2安装ubuntu20
为了性能买了个游戏本机械革命z2,但还是想用上linux,身为程序员习惯了linux的开发环境有点离不开.但是之前尝试安装deepin或者linux都失败了,一是N卡条件下安装过程和安装之后的显示有问 ...
- npm 操作代码
npm cache clean -force //强制清除缓,比如安装echarts失败后,清除,在安装
- 『心善渊』Selenium3.0基础 — 13、Selenium操作下拉菜单
目录 1.使用Selenium中的Select类来处理下拉菜单(推荐) 2.下拉菜单对象的其他操作(了解) 3.通过元素二次定位方式操作下拉菜单(重点) (1)了解元素二次定位 (2)示例: 页面中的 ...
- base64的实现原理
base64是处理二进制数据的一种编码方式,可用于把二进制数据编码成64个可打印的字符. 学习base64之前,先了解一下什么是字节与编码 什么是字节 互联网中的数据都是用字节来表示的,一个字节有8位 ...
- Web自动化之iframe切换
一.如何判断元素是否在iframe中 选中要操作的元素,通过下方的父节点查看是否存在iframe,存在则元素在iframe,需要切换至iframe中进行元素的操作 二.iframe切换方式一 1.方式 ...
- Libevent2.1.8版在Liunx中编译安装遇到的问题
Libevent2.1.8版在Liunx中编译安装遇到的问题 前言:在网上找了很久,都没有一个明确的解决方法,通过分析可能的原因,将自己实际操作及解决的成功结果记录如下,以供遇到相似的问题,能提供思路 ...
- SonarQube 概述与安装
SonarQube 概述 是一种自动代码审查工具,用于检测代码中的错误.漏洞和代码异味.它可以与您现有的工作流程集成,以支持跨项目分支和拉取请求的持续代码检查. 在一个典型的开发过程中 开发人员在 I ...
- CentOS-搭建MinIO集群
一.基础环境 操作系统:CentOS 7.x Minio在线演示 Minio下载 二.准备工作 2.1.机器资源 192.168.1.101 /data1 192.168.1.102 /data2 1 ...