题意:

给一棵\(n(1 \leq n \leq 10^5)\)个节点的二叉树,除叶子节点外,每个点都有左儿子和右儿子。

每个点上都有一个权值。

游戏规则是这样的:在根节点放一个权值为\(X\)的小球,假设当前节点的权值是\(w_i\)

  • 如果\(X=w_i\),小球就停在这个节点。
  • 如果\(X<w_i\),小球等概率地往左右两个儿子走下去。
  • 如果\(X>w_i\),小球以\(\frac{1}{8}\)的概率走到左儿子,以\(\frac{7}{8}\)的概率走到右儿子。

下面有若干次询问\(v \, X\),问从根节点放一个权值为\(X\)的小球走到节点\(v\)的概率是多少。

分析:

构造一棵主席树,维护父亲权值在区间\([L,R]\)中左儿子和右儿子的个数。

首先判断一下概率为\(0\)的情况,如果找到父亲权值等于小球权值\(X\)的点,那么概率为\(0\)。

否则就统计一下父亲权值小于\(X\)的左儿子个数\(lcnt\),右儿子个数\(rcnt\),以及所有的儿子个数\(sons\)。

所求的概率为:\(p=\frac{1^{lcnt} \cdot 7^{rcnt} \cdot 4^{sons-lcnt-rcnt}}{8}\)

解得\(x=rcnt, \, y=sons+lcnt+rcnt\)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 100000 + 10;
const int maxnode = maxn << 5; struct Node
{
int lcnt, rcnt;
Node(int l = 0, int r = 0): lcnt(l), rcnt(r) {}
Node operator + (const Node& t) const {
return Node(lcnt + t.lcnt, rcnt + t.rcnt);
}
}; int sz;
Node T[maxnode];
int lch[maxnode], rch[maxnode];
int root[maxn]; int update(int pre, int L, int R, int pos, Node t) {
int rt = ++sz;
T[rt] = T[pre] + t;
lch[rt] = lch[pre];
rch[rt] = rch[pre];
if(L < R) {
int M = (L + R) / 2;
if(pos <= M) lch[rt] = update(lch[pre], L, M, pos, t);
else rch[rt] = update(rch[pre], M+1, R, pos, t);
}
return rt;
} int n, m, Q;
int a[maxn], b[maxn * 2], tot;
int v[maxn], x[maxn];
int ch[maxn][2];
int dep[maxn]; void dfs(int u) {
if(!ch[u][0]) return;
root[ch[u][0]] = update(root[u], 1, tot, a[u], Node(1, 0));
root[ch[u][1]] = update(root[u], 1, tot, a[u], Node(0, 1));
dep[ch[u][0]] = dep[ch[u][1]] = dep[u] + 1;
dfs(ch[u][0]);
dfs(ch[u][1]);
} bool queryequal(int rt, int L, int R, int pos) {
if(L == R) { return T[rt].lcnt + T[rt].rcnt != 0; }
int M = (L + R) / 2;
if(pos <= M) return queryequal(lch[rt], L, M, pos);
else return queryequal(rch[rt], M+1, R, pos);
} Node queryless(int rt, int L, int R, int pos) {
if(R <= pos) return T[rt];
int M = (L + R) / 2;
if(pos <= M) return queryless(lch[rt], L, M, pos);
else return T[lch[rt]] + queryless(rch[rt], M+1, R, pos);
} int main()
{
int _; scanf("%d", &_);
while(_--) {
int n; scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", a + i);
b[i - 1] = a[i];
}
scanf("%d", &m);
memset(ch, 0, sizeof(ch));
while(m--) {
int u; scanf("%d", &u);
scanf("%d%d", &ch[u][0], &ch[u][1]);
}
scanf("%d", &Q);
tot = n;
for(int i = 1; i <= Q; i++) {
scanf("%d%d", v + i, x + i);
b[tot++] = x[i];
} sort(b, b + tot);
tot = unique(b, b + tot) - b;
for(int i = 1; i <= n; i++)
a[i] = lower_bound(b, b + tot, a[i]) - b + 1;
for(int i = 1; i <= Q; i++)
x[i] = lower_bound(b, b + tot, x[i]) - b + 1; sz = 0;
dfs(1); for(int i = 1; i <= Q; i++) {
if(queryequal(root[v[i]], 1, tot, x[i])) {
printf("0\n"); continue;
}
Node ans;
if(x[i] > 1) ans = queryless(root[v[i]], 1, tot, x[i] - 1);
int sons = dep[v[i]];
int ans2 = sons * 3;
ans2 -= (sons - ans.lcnt - ans.rcnt) * 2;
int ans7 = ans.rcnt;
printf("%d %d\n", ans7, ans2);
}
} return 0;
}

HDU 4605 Magic Ball Game 主席树的更多相关文章

  1. HDU 4605 Magic Ball Game (在线主席树|| 离线 线段树)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意:给出一棵二叉树,每个结点孩子数目为0或者2. ...

  2. hdu 4605 Magic Ball Game (在线主席树/离线树状数组)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4605 题意: 有一颗树,根节点为1,每一个节点要么有两个子节点,要么没有,每个节点都有一个权值wi .然后,有一个球,附带值x . 球 ...

  3. HDU 4605 Magic Ball Game(可持续化线段树,树状数组,离散化)

    Magic Ball Game Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  4. hdu 4605 Magic Ball Game

    http://acm.hdu.edu.cn/showproblem.php?pid=4605 可以离线求解 把所以可能出现的 magic ball  放在一个数组里(去重),从小到大排列 先不考虑特殊 ...

  5. HDU 4605 Magic Ball Game (dfs+离线树状数组)

    题意:给你一颗有根树,它的孩子要么只有两个,要么没有,且每个点都有一个权值w. 接着给你一个权值为x的球,它从更节点开始向下掉,有三种情况 x=w[now]:停在此点 x<w[now]:当有孩子 ...

  6. HDU 4605 Magic Ball Game 树状数组

    题目大意很简单. 有一颗树(10^5结点),所有结点要么没有子结点,要么有两个子结点.然后每个结点都有一个重量值,根结点是1 然后有一个球,从结点1开始往子孙结点走. 每碰到一个结点,有三种情况 如果 ...

  7. HDU 4605 Magic Ball Game(离线算法)

    题目链接 思路就很难想+代码实现也很麻烦,知道算法后,已经写的很繁琐而且花了很长时间,200+,好久没写过这么长的代码了. #pragma comment(linker, "/STACK:1 ...

  8. HDU 4602 Magic Ball Game(离线处理,树状数组,dfs)

    Magic Ball Game Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  9. HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

随机推荐

  1. SpringCloud 分布式配置中心

    SpringCloud 分布式配置中心 服务端 创建工程并完善结构 国际惯例,把maven工程创建完善 pom.xml <?xml version="1.0" encodin ...

  2. 第12届D2前端技术论坛

    第12届D2前端技术论坛 最近参加了阿里的D2前端技术论坛,听了一天的报告,收获良多,下面对几场报告做一个记录. 自己选择听的主线也是从: 实践应用 -> 管理 -> 性能 -> 新 ...

  3. js页面可视区域懒加载

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. ubuntu和window之间如何共享文件

    参考网上的自己动手实现共享文件: 1.打开虚拟机进入ubuntu系统,先安装增强功能包 2.安装完重启虚拟机后,在window下创建一个专门用来共享的文件夹 3.切换到ubuntu系统,在设备的共享文 ...

  5. 【Unity3D】实现太阳系

    实践要求:写一个程序,实现一个完整的太阳系,其他星球围绕太阳的转速必须不一样,并且不再一个法平面内. 法平面是指过空间曲线的切点,且与切线垂直的平面.要求不在一个法平面内,则在保证所有行星以及太阳在一 ...

  6. 【LeetCode】4.Median of Two Sorted Arrays 两个有序数组中位数

    题目: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ...

  7. Windows系统下查看文件编码类型

    这是一个程序员的最基本的技能,原谅我到现在才去了解 以前只知道window操作系统下文件大部分默认编码是ANSI,中文版是GBK编码 如果想要查看或者修改文件编码的话有两种方式 一:用记事本打开文件, ...

  8. 监测元素resize

    前言 近来有需求要做分页,听起来可能有点Low. 所以我要把Low的事情做得有点逼格. 分页本身没啥,但是数据量起来了,比如十万. 要是不做点处理, 那你的页面估计爽得很,机器也爽得很. 放心,我不会 ...

  9. HDU 2089 不要62 (数位DP,入门)

    题意: 只要含连续的62,或者含4的车牌号码都是不吉利的,其他都是吉利的组合.问区间[L,R]中有多少个数是吉利的? 思路: 依然是利用树(10进制是十叉树)的思想,统计左边所有子树有多少个数是吉利的 ...

  10. 【Python图像特征的音乐序列生成】关于数据库到底在哪里下载

    毕竟原网站一个是14年前的一个是16年前的…… 1,http://ifdo.ca/~seymour/nottingham/nottingham.html 这个网站可以下载zip包. 2,https:/ ...