BZOJ_3133_[Baltic2013]ballmachine_堆+倍增

Description

有一个装球机器,构造可以看作是一棵树。有下面两种操作:

  • 从根放入一个球,只要下方有空位,球会沿着树滚下。如果同时有多个点可以走,那么会选择编号最小的节点所在路径的方向。比如依次在树根4放2个球,第一个球会落到1,第二个会落到3
  • 从某个位置拿走一个球,那么它上方的球会落下来。比如依次拿走5, 7, 8三个球:

Input

第一行:球的个数N,操作个数QN, Q <= 100 000)下面N行:第i个节点的父亲。如果是根,则为0 接下来Q行:op num

  1. op == 1:在根放入num个球
  2. op == 2:拿走在位置num的球

Output

保证输入合法

  1. op == 1:输出最后一个球落到了哪里
  2. op == 2:输出拿走那个球后有多少个球会掉下来

Sample Input

8 4
0
1
2
2
3
3
4
6
1 8
2 5
2 7
2 8

Sample Output

1
3
2
2


可以发现球的位置顺序是固定的,预处理出来每个点应该被放入小球的优先度,然后这个可以把边表排序之后dfs一遍求出。

用一个堆来维护当前没被放入的球的编号。

删除时倍增祖先,找到第一个没被放球的位置即可。

代码:

#include <cstdio>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define N 200050
priority_queue<int>q;
vector <int> v[N];
int n,T,mn[N],dfn[N],idx[N],tdfn[N],tidx[N],c[N],vis[N],f[21][N],dep[N],rt,son[N];
bool cmp(int x,int y) {
return mn[x]<mn[y];
}
void dfs(int x) {
int i;
int t=v[x].size(); mn[x]=x;
for(i=0;i<t;i++) {
f[0][v[x][i]]=x;
dep[v[x][i]]=dep[x]+1;
dfs(v[x][i]);
mn[x]=min(mn[x],mn[v[x][i]]);
}
sort(&v[x][0],&v[x][t],cmp);
}
void solve(int x) {
int i,t=v[x].size();
for(i=0;i<t;i++) {
solve(v[x][i]);
}
idx[x]=++idx[0];
tidx[idx[0]]=x;
}
int main() {
scanf("%d%d",&n,&T);
int i,x,y,j;
for(i=1;i<=n;i++) {
scanf("%d",&x);
if(!x) rt=i;
else v[x].push_back(i);
}
for(i=1;i<=n;i++) {
q.push(-i);
}
dep[rt]=1;
dfs(rt);
solve(rt);
for(i=1;(1<<i)<=n;i++) {
for(j=1;j<=n;j++) {
f[i][j]=f[i-1][f[i-1][j]];
}
}
int opt;
while(T--) {
scanf("%d%d",&opt,&x);
if(opt==1) {
while(x--) {
y=tidx[-q.top()]; q.pop();
vis[y]=1;
}
printf("%d\n",y);
}else {
int t=x;
for(i=20;i>=0;i--) {
if(vis[f[i][x]]) x=f[i][x];
}
vis[x]=0;
printf("%d\n",dep[t]-dep[x]);
q.push(-idx[x]);
}
}
}

BZOJ_3133_[Baltic2013]ballmachine_堆+倍增的更多相关文章

  1. [BZOJ3133] [Baltic2013]ballmachine(树上倍增+堆)

    [BZOJ3133] [Baltic2013]ballmachine(树上倍增+堆) 题面 有一个装球机器,构造可以看作是一棵树.有下面两种操作: 从根放入一个球,只要下方有空位,球会沿着树滚下.如果 ...

  2. BZOJ5415[Noi2018]归程——kruskal重构树+倍增+堆优化dijkstra

    题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n).我们依次用 l,a 描述一条边的长度.海 ...

  3. 【BZOJ 3133】 3133: [Baltic2013]ballmachine (线段树+倍增)

    3133: [Baltic2013]ballmachine Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 148  Solved: 66 Descri ...

  4. Codeforces 828F Best Edge Weight - 随机堆 - 树差分 - Kruskal - 倍增算法

    You are given a connected weighted graph with n vertices and m edges. The graph doesn't contain loop ...

  5. CF827D Best Edge Weight[最小生成树+树剖/LCT/(可并堆/set启发式合并+倍增)]

    题意:一张图求每条边边权最多改成多少可以让所有MST都包含这条边. 这题还是要考察Kruskal的贪心过程. 先跑一棵MST出来.然后考虑每条边. 如果他是非树边,要让他Kruskal的时候被选入,必 ...

  6. [CF1051F]The Shortest Statement_堆优化dij_最短路树_倍增lca

    The Shortest Statement 题目链接:https://codeforces.com/contest/1051/problem/F 数据范围:略. 题解: 关于这个题,有一个重要的性质 ...

  7. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

  8. BZOJ 2819: Nim dfs序维护树状数组,倍增

    1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家.2.把堆v中的石子数变为k. 分析: ...

  9. BZOJ3133[ballmachine]——倍增+优先队列

    题目描述 有一个装球机器,构造可以看作是一棵树.有下面两种操作: 从根放入一个球,只要下方有空位,球会沿着树滚下.如果同时有多个点可以走,那么会选择编号最小的节点所在路径的方向.比如依次在树根4放2个 ...

随机推荐

  1. assert.deepEqual()

    assert.deepEqual(actual, expected[, message]) 深度比较 actual 和 expected 参数,使用比较运算符(==)比较原始值. 只考虑可枚举的&qu ...

  2. buf.compare()

    buf.compare(otherBuffer) otherBuffer {Buffer} 返回:{Number} 比较两个 Buffer 实例,无论 buf 在排序上靠前.靠后甚至与 otherBu ...

  3. HTML5地理定位-Geolocation API

    HTML5提供了一组Geolocation API,来自navigator定位对象的子对象,获取用户的地理位置信息Geolocation API使用方法:1.判断是否支持 navigator.geol ...

  4. ecshop 修改支持php7 方案

    修改方法 http://jsb.php-php.com/2016/05/472/ 修改数据库配置 data/config.php

  5. [Android] java代码无错误,但跳转失败

    今天在调代码的时候,出现了这样的问题,我晕了半天,才找到解决办法. 查看日志发现:Initialize Binary Program Cache: Load Failed 从来没见过这种问题,Java ...

  6. 《C语言程序设计(第四版)》阅读心得(一)

    本篇开始写我个人觉得谭浩强老师的<C语言程序设计(第四版)>中之前没有认识到,或者忘了的知识.因为本科学过,所以有些简单的东西就没有放进来了,所以可能并不是太全面. 第一章程序设计与语言 ...

  7. [luoguP1021] 邮票面值设计(DFS + dp)

    传送门 数据很小,可以DFS,判断的时候用背包DP 然而不知到枚举到哪里.... 首先枚举前可以求一遍题目中的MAX,下一层DFS的时候可以只枚举到MAX + 1,因为再往上就必定会出现断层 蒟蒻很菜 ...

  8. bzoj1007 [HNOI2008]水平可见直线 - 几何 - hzwer.com

    Description Input 第一行为N(0 < N < 50000),接下来的N行输入Ai,Bi Output 从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必 ...

  9. struct init

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h& ...

  10. php的socket通信【转载】

     对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1.         什么是TCP/IP.UDP?2.         Soc ...