BZOJ3133[ballmachine]——倍增+优先队列
题目描述
有一个装球机器,构造可以看作是一棵树。有下面两种操作:
- 从根放入一个球,只要下方有空位,球会沿着树滚下。如果同时有多个点可以走,那么会选择编号最小的节点所在路径的方向。比如依次在树根
4
放2个球,第一个球会落到1
,第二个会落到3
:
- 从某个位置拿走一个球,那么它上方的球会落下来。比如依次拿走
5, 7, 8
三个球:
输入
第一行:球的个数N
,操作个数Q
(N, Q <= 100 000
)下面N
行:第i
个节点的父亲。如果是根,则为0
接下来Q
行:op num
op == 1
:在根放入num
个球op == 2
:拿走在位置num
的球
输出
保证输入合法
op == 1
:输出最后一个球落到了哪里op == 2
:输出拿走那个球后有多少个球会掉下来
样例输入
0
1
2
2
3
3
4
6
1 8
2 5
2 7
2 8
样例输出
3
2
2
- #include<cstdio>
- #include<algorithm>
- #include<iostream>
- #include<cmath>
- #include<cstring>
- #include<vector>
- #include<queue>
- using namespace std;
- priority_queue< int,vector<int>,greater<int> >q;
- vector<int>v[200010];
- int n,Q;
- int f[20][200010];//倍增祖先
- int m[200010];//子树最小的编号
- int s[200010];//优先度
- int r[200010];//优先度对应节点
- int cnt;
- int root;
- int x,y;
- int opt;
- int d[200010];//深度
- int vis[200010];//是否被填标记
- bool cmp(int x,int y)
- {
- return m[x]<m[y];
- }
- void dfs(int x)//按子树最小编号大小排序并处理深度
- {
- m[x]=x;
- for(int i=0;i<v[x].size();i++)
- {
- f[0][v[x][i]]=x;
- d[v[x][i]]=d[x]+1;
- dfs(v[x][i]);
- m[x]=min(m[x],m[v[x][i]]);
- }
- sort(&v[x][0],&v[x][v[x].size()],cmp);
- }
- void getsign(int x)//处理优先度
- {
- for(int i=0;i<v[x].size();i++)
- {
- getsign(v[x][i]);
- }
- s[x]=++cnt;
- r[cnt]=x;
- }
- int main()
- {
- scanf("%d%d",&n,&Q);
- for(int i=1;i<=n;i++)
- {
- scanf("%d",&x);
- if(x==0)
- {
- root=i;
- }
- else
- {
- v[x].push_back(i);
- }
- }
- for(int i=1;i<=n;i++)
- {
- q.push(i);
- }
- d[root]=1;
- dfs(root);
- getsign(root);
- for(int i=1;i<=20;i++)
- {
- for(int j=1;j<=n;j++)
- {
- f[i][j]=f[i-1][f[i-1][j]];
- }
- }
- while(Q--)
- {
- scanf("%d%d",&opt,&x);
- if(opt==1)
- {
- while(x--)
- {
- y=r[q.top()];
- q.pop();
- vis[y]=1;
- }
- printf("%d\n",y);
- }
- else
- {
- int fa=x;
- for(int i=20;i>=0;i--)
- {
- if(vis[f[i][x]]==1)
- {
- x=f[i][x];
- }
- }
- vis[x]=0;
- printf("%d\n",d[fa]-d[x]);
- q.push(s[x]);
- }
- }
- }
BZOJ3133[ballmachine]——倍增+优先队列的更多相关文章
- CF786C-Till I Collapse【树状数组倍增,优先队列】
正题 题目链接:https://www.luogu.com.cn/problem/CF786C 题目大意 给出一个长度为\(n\)的序列. 对于每个\(k\in[1,n]\)求将\(n\)分成最少的段 ...
- [BZOJ3133] [Baltic2013]ballmachine(树上倍增+堆)
[BZOJ3133] [Baltic2013]ballmachine(树上倍增+堆) 题面 有一个装球机器,构造可以看作是一棵树.有下面两种操作: 从根放入一个球,只要下方有空位,球会沿着树滚下.如果 ...
- bzoj4458 GTY的OJ (优先队列+倍增)
把超级钢琴放到了树上. 这次不用主席树了..本来以为会好写一点没想到细节更多(其实是树上细节多) 为了方便,对每个点把他的那个L,R区间转化成两个深度a,b,表示从[a,b)选一个最小的前缀和(到根的 ...
- 【BZOJ 3133】 3133: [Baltic2013]ballmachine (线段树+倍增)
3133: [Baltic2013]ballmachine Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 148 Solved: 66 Descri ...
- [Baltic2013]ballmachine BZOJ3133
分析: 我们考虑,因为每次放置的时候,都是向子树中含有的编号最小的哪一个走,那么放置的顺序是固定的,我们将边以to的子树最小排序,之后得到的出栈序就是球的放入顺序.目测可以使用堆来实现,线段树也能实现 ...
- BZOJ3133[Baltic2013]ballmachine
题目描述 https://www.lydsy.com/JudgeOnline/problem.php?id=3133 题解 还是分两个操作来说吧. 先看第一个操作,放球,可以发现,对于祖先节点和后代节 ...
- Problem 1016 咒文卷轴 优先队列+前缀和+rmq
题目链接: 题目 Problem 1016 咒文卷轴 Time Limit: 3000 mSec Memory Limit : 131072 KB 问题描述 小Y 是一个魔法师,有一天他获得了一卷神秘 ...
- BZOJ 4144 Dijkstra+Kruskal+倍增LCA
思路: 先把所有的加油站 push进按weight排序的优先队列里 对于每个不是加油站的点 找到到它的点的最短路以及它来源的加油站 如果x和y有边 且x和y加油站的来源不一样 则它可以连边 跑一边Kr ...
- PAT1057 Stack(树状数组+倍增)
目录 题目大意 题目分析 题目大意 要求维护一个栈,提供压栈.弹栈以及求栈内中位数的操作(当栈内元素\(n\)为偶数时,只是求第\(n/2\)个元素而非中间两数的平均值).最多操作100000次,压栈 ...
随机推荐
- DOM(三)
Text类型 文本节点由Text类型表示,包含的是可以照字面解释的纯文本内容,纯文本中可以包含转义后的HTML字符,但不包含HTML代码,Text节点具有以下特征: nodeType值为3: node ...
- Gradle构建工具从入门到精通(IDEA)
1.Gradle安装 官网下载压缩包,然后解压,配置本地环境变量.主要有下面两个: GRADLE_HOME 是解压后的目录, GRADLE_USER_HOME 的作用是让其他程序检测到本地.gradl ...
- 单链表的基本操作--c++
#include <iostream> //实现单链表的建立,测长和打印 #include <string> using namespace std; struct node ...
- Full Regularization Path for Sparse Principal Component Analysis
目录 背景 Notation Sparse PCA Semidefinite Relaxation Low Rank Optimization Sorting and Thresholding 背景 ...
- Linux安装Apache常见报错(一)
启动Apache提示报错:Could not reliably determine the server's fully qualified domain name, using localhost, ...
- 【转】mysql热备
mysql双机热备的实现 亲测可用
- iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏)
iOS中的截屏(屏幕截屏及scrollView或tableView的全部截屏) 2017.03.16 12:18* 字数 52 阅读 563评论 4喜欢 2 1. 截取屏幕尺寸大小的图片并保存至相册 ...
- [转帖]分布式Unique ID的生成方法一览
分布式Unique ID的生成方法一览 http://www.importnew.com/22211.html 分布式的Unique ID的用途如此广泛,从业务对象Id到日志的TraceId,本文总结 ...
- emplace与insert的区别(C++11)
转自时习之 C++11中大部分的容器对于添加元素除了传统的 insert 或者 pusb_back/push_front 之外都提供一个新的函数叫做 emplace. 比如如果你想要向 std::ve ...
- YAML配置:mapping values are not allowed here
在配置Eureka服务器配置文件的时候,出现了mapping values not allowed here的错误,原因是的冒号 ”:“后面没有空格. 原因分析:yml文件中,键值对是以": ...