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. Codeforces 193 D. Two Segments

    http://codeforces.com/contest/193/problem/D 题意: 给一个1~n的排列,在这个排列中选出两段区间,求使选出的元素排序后构成公差为1的等差数列的方案数. 换个 ...

  2. [SDOI2014]旅行

    洛谷 P3313 [SDOI2014]旅行 https://www.luogu.org/problem/show?pid=3313 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接 ...

  3. 流程控制语句(MySQL/MariaDB )

    本文目录:1.BEGIN...END2.true和false3.if结构4.case结构5.loop.leave和iterate6.repeat循环7.while循环 MySQL/MariaDB中的符 ...

  4. C语言Linix服务器网络爬虫项目(二)项目设计和通过一个http请求抓取网页的简单实现

    我们通过上一篇了解了爬虫具体要实现的工作之后,我们分析得出的网络爬虫的基本工作流程如下: 1.首先选取一部分精心挑选的种子URL: 2.将这些URL放入待抓取URL队列: 3.从待抓取URL队列中取出 ...

  5. linux下的Shell编程(6)case和select

    第一个,除了if语句之外,Shell Script中也有类似C语言中多分支结构的case语句,它的语法是: case var in pattern 1 ) - ;; pattern 2 ) - ;; ...

  6. maven入门(1-4)使用eclipse构建maven项目

    1. 安装m2eclipse插件    要用Eclipse构建Maven项目,我们需要先安装meeclipse插件    点击eclipse菜单栏Help->Eclipse Marketplac ...

  7. Ubuntu下发射wifi

    iphone要连接的话,mode选Ad-hoc, wifi密码要用WEP 40/128-bit key模式

  8. 南阳OJ-6-喷水装置(一)

    题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=6 题目大意: 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷 ...

  9. 一、WINDOWS下 RabbitMQ安装部署

    安装需要用管理员权限,全部右键管理员身份运行.建议安装到虚拟机里面,免得影响日常使用. 1.下载   https://dl.bintray.com/rabbitmq/all/rabbitmq-serv ...

  10. Spring Cloud学习笔记-005

    服务消费者 之前已经搭建好了微服务中的核心组件——服务注册中心(包括单节点模式和高可用模式).也有了服务提供者,接下来搭建一个服务消费者,它主要完成两个目标,发现服务以及消费服务.其中,服务发现的任务 ...