Magic Ball Game

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2189    Accepted Submission(s): 634

Problem Description
When the magic ball game turns up, Kimi immediately falls in it. The interesting game is made up of N balls, each with a weight of w[i]. These N balls form a rooted tree, with the 1st ball as the root. Any ball in the game has either 0 or 2 children ball. If
a node has 2 children balls, we may define one as the left child and the other as the right child.
The rules are simple: when Kimi decides to drop a magic ball with a weight of X, the ball goes down through the tree from the root. When the magic ball arrives at a node in the tree, there's a possibility to be catched and stop rolling, or continue to roll
down left or right. The game ends when the ball stops, and the final score of the game depends on the node at which it stops.
After a long-time playing, Kimi now find out the key of the game. When the magic ball arrives at node u weighting w[u], it follows the laws below:
1  If X=w[u] or node u has no children balls, the magic ball stops.
2  If X<w[u], there's a possibility of 1/2 for the magic ball to roll down either left or right.
3  If X>w[u], the magic ball will roll down to its left child in a possibility of 1/8, while the possibility of rolling down right is 7/8.
In order to choose the right magic ball and achieve the goal, Kimi wonders what's the possibility for a magic ball with a weight of X to go past node v. No matter how the magic ball rolls down, it counts if node v exists on the path that the magic ball goes
along.
Manual calculating is fun, but programmers have their ways to reach the answer. Now given the tree in the game and all Kimi's queries, you're required to answer the possibility he wonders.
 
Input
The input contains several test cases. An integer T(T≤15) will exist in the first line of input, indicating the number of test cases.
Each test case begins with an integer N(1≤N≤105), indicating the number of nodes in the tree. The following line contains N integers w[i], indicating the weight of each node in the tree. (1 ≤ i ≤ N, 1 ≤ w[i] ≤ 109, N is odd)
The following line contains the number of relationships M. The next M lines, each with three integers u,a and b(1≤u,a,b≤N), denotes that node a and b are respectively the left child and right child of node u. You may assume the tree contains exactly N nodes
and (N-1) edges.
The next line gives the number of queries Q(1≤Q≤105). The following Q lines, each with two integers v and X(1≤v≤N,1≤X≤109), describe all the queries.
 
Output
If the magic ball is impossible to arrive at node v, output a single 0. Otherwise, you may easily find that the answer will be in the format of 7x/2y . You're only required to output the x and y for each query, separated by a blank. Each
answer should be put down in one line.
 
Sample Input
1
3
2 3 1
1
1 2 3
3
3 2
1 1
3 4
 
Sample Output
0
0 0
1 3
 
Source
/*
hdu4605 树状数组+离散化+dfs
一个很明显的错误,在网上找了几个测试案例居然都过了TAT,也是无语
最开始发现可以通过判断你走到当前节点左右的次数 和 比你小的个数 比X大 1/2 1/2 比X小 1/8 7/8
相当于比X大时有一个2,当比X小时有3个2 7则看情况。
所以可以遍历树,然后判断。 比当前数小的数的个数则用树状数组维护 但是最开始写出来翻了很2的错误,我只保存了到当前节点小的数个数
(即没有区分左右)以及左右次数,但实际上这样并不能得出有多少次在比它小
的时候往右走即7/8的次数 于是乎把树状数组保存的内容弄成二维的就好了。然后就是最开始的离散化了
hhh-2016-03-03 22:57:09
*/
#include <algorithm>
#include <cmath>
#include <queue>
#include <iostream>
#include <cstring>
#include <map>
#include <cstdio>
#include <vector>
#include <functional>
using namespace std;
typedef long long ll;
const int maxn = 150050;
const int inf = 0x3f3f3f3f;
int s[maxn*2][2];
int n,tot;
int ans[maxn][2];
int vec[maxn*2];
int vis[maxn];
struct node
{
int val;
int l,r;
} pnode[maxn]; vector<pair<int,int> >qu[maxn];
int lowbit(int x)
{
return x&(-x);
} void add(int x,int val,int i)
{
while(x <= tot)
{
s[x][i]+=val;
x += lowbit(x);
}
} int sum(int x,int i)
{
int cnt = 0;
while(x)
{
cnt += s[x][i];
x -= lowbit(x);
}
return cnt;
} void dfs(int u,int l,int r)
{
int lson=pnode[u].l,rson=pnode[u].r,pos;
for(int i = 0; i < (int)qu[u].size(); i++)
{
int id = qu[u][i].first;
int lim = qu[u][i].second;
pos = lower_bound(vec,vec+tot,lim)-vec+1;
int ls = sum(pos-1,0);
int rs = sum(pos-1,1);
int lls = sum(pos,0);
int rrs = sum(pos,1);
if(ls+rs != lls+rrs)
{
ans[id][0] = -1;
continue;
}
ans[id][0] = (ls+rs)*2+l+r;
ans[id][1] = rs;
}
pos = lower_bound(vec,vec+tot,pnode[u].val)-vec+1; if(lson != -1)
{
add(pos,1,0);
dfs(lson,l+1,r);
add(pos,-1,0);
}
if(rson != -1)
{
add(pos,1,1);
dfs(rson,l,r+1);
add(pos,-1,1);
}
return ;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(s,0,sizeof(s));
memset(ans,0,sizeof(ans));
int m,q,M,v;
tot = 0;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
scanf("%d",&pnode[i].val);
pnode[i].l = pnode[i].r = -1;
vec[tot++] = (pnode[i].val);
}
scanf("%d",&m);
for(int i =1; i <= m; i++)
{
int x;
scanf("%d",&x);
scanf("%d%d",&pnode[x].l,&pnode[x].r);
}
scanf("%d",&q);
for(int i =1; i <= q+n; i++)qu[i].clear();
for(int i =1; i <= q; i++)
{
scanf("%d%d",&v,&M);
qu[v].push_back(make_pair(i,M));
vec[tot++] = M;
}
sort(vec,vec+tot);
tot = unique(vec,vec+tot)-vec;
dfs(1,0,0);
for(int i =1; i <=q ; i++)
{
if(ans[i][0] == -1)
printf("0\n");
else
printf("%d %d\n",ans[i][1],ans[i][0]);
}
}
return 0;
}

  

hdu4605 树状数组+离散化+dfs的更多相关文章

  1. (好题)树状数组+离散化+DFS序+离线/莫队 HDOJ 4358 Boring counting

    题目传送门 题意:给你一棵树,树上的每个节点都有树值,给m个查询,问以每个点u为根的子树下有多少种权值恰好出现k次. 分析:首先要对权值离散化,然后要将树形转换为线形,配上图:.然后按照右端点从小到大 ...

  2. BZOJ_5055_膜法师_树状数组+离散化

    BZOJ_5055_膜法师_树状数组+离散化 Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然 ...

  3. BZOJ3881[Coci2015]Divljak——AC自动机+树状数组+LCA+dfs序+树链的并

    题目描述 Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...

  4. POJ 2299 【树状数组 离散化】

    题目链接:POJ 2299 Ultra-QuickSort Description In this problem, you have to analyze a particular sorting ...

  5. BZOJ 3881 [COCI2015]Divljak (Trie图+Fail树+树链的并+树状数组维护dfs序)

    题目大意: Alice有n个字符串S_1,S_2...S_n,Bob有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: “1 P”,Bob往自己的集合里添加了一个字符串P. ...

  6. HDU-4605 Magic Ball Game 树状数组+离散+dfs

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4605 题意:给一颗树,每个节点有个权值w[u],每个节点只有两个儿子或者没有儿子,从根节点放下一个小球 ...

  7. HDU5877 Weak Pair dfs + 线段树/树状数组 + 离散化

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5877 题意: weak pair的要求: 1.u是v的祖先(注意不一定是父亲) 2.val[u]*va ...

  8. hdu 5877 Weak Pair dfs序+树状数组+离散化

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Prob ...

  9. 线段树合并 || 树状数组 || 离散化 || BZOJ 4756: [Usaco2017 Jan]Promotion Counting || Luogu P3605 [USACO17JAN]Promotion Counting晋升者计数

    题面:P3605 [USACO17JAN]Promotion Counting晋升者计数 题解:这是一道万能题,树状数组 || 主席树 || 线段树合并 || 莫队套分块 || 线段树 都可以写..记 ...

随机推荐

  1. 在arc模式下 CGImage 释放问题

    //大图bigImage //定义myImageRect,截图的区域 if (imagecount >= 3) { CGRect myImageRect; if (i.size.width< ...

  2. Android Notification setLatestEventInfo方法已废弃

    代替setLatestEventInfo的方法是用Notification.Builder创建Builder对象,通过该对象设置Notification相关属性. otification.Builde ...

  3. nyoj 公约数和公倍数

    公约数和公倍数 时间限制:1000 ms  |  内存限制:65535 KB 难度:1   描述 小明被一个问题给难住了,现在需要你帮帮忙.问题是:给出两个正整数,求出它们的最大公约数和最小公倍数. ...

  4. CentOS7 防火墙firewalld详细操作

    1.firewalld的基本使用 启动: systemctl start firewalld 查看状态: systemctl status firewalld  停止: systemctl disab ...

  5. python之路--day13-模块

    1,什么是模块 模块就是系统功能的集合体,在python中,一个py文件就是一个模块, 例如:module.py 其中module叫做模块名 2,使用模块 2.1 import导入模块 首次带入模块发 ...

  6. Angular 学习笔记 ( PWA + App Shell )

    PWA (Progressive Web Apps) 是未来网页设计的方向. 渐进式网站. Angular v5 开始支持 pwa 网站 (所谓支持意思是说有一些 build in 的方法和规范去实现 ...

  7. 新概念英语(1-125)Tea for two

    Does Susan have tea by herself?A:Can't you come in and have tea now,Peter? Not yet.B:I must water th ...

  8. python的单元测试

    单元测试实际上就是一些"断言"(assert)代码 断言就是判断一个函数或对象的一个方法所产生的结果是否符合你期望的那个结果. python中assert断言是声明布尔值为真的判定 ...

  9. NetSNMP开源代码学习——小试牛刀

    原创作品,转载请注明出处,严禁非法转载.如有错误,请留言! email:40879506@qq.com 题外话:技术越是古董级的东西,越是值得学习. 一. 配置 参考: http://www.cnbl ...

  10. scrapy spider官方文档

    Spiders Spider类定义了如何爬取某个(或某些)网站.包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item). 换句话说,Spider就是您定义爬取的动作 ...