Magic Ball Game

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

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
 
Recommend
liuyiding
 

离线之后,对树进行一次dfs.

用两个树状数组,分别代表往左和往右的节点的值。

递归dfs的,会爆栈,手动加栈后,只有C++可以过。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std; const int MAXN = ;
int next[MAXN][];
int n;
int root;
int w[MAXN];
struct QQ
{
int v;
int X;
int ans1,ans2;
}Query[MAXN];
vector<int>vec[MAXN];
bool used[MAXN];
int a[MAXN];
map<int,int>mp; int c1[MAXN];
int c2[MAXN];
int t;
int lowbit(int x)
{
return x&(-x);
}
void add1(int i,int val)
{
while(i <= t)
{
c1[i] += val;
i += lowbit(i);
}
}
int sum1(int i)
{
int s = ;
while(i > )
{
s += c1[i];
i -= lowbit(i);
}
return s;
}
void add2(int i,int val)
{
while(i <= t)
{
c2[i] += val;
i += lowbit(i);
}
}
int sum2(int i)
{
int s = ;
while(i > )
{
s += c2[i];
i -= lowbit(i);
}
return s;
} void dfs(int u)
{
int sz = vec[u].size();
for(int i = ;i < sz;i++)
{
int id = vec[u][i];
int X = mp[Query[id].X];
if(sum1(X)-sum1(X-)!= || sum2(X)-sum2(X-)!=)
{
Query[id].ans1 = Query[id].ans2 = -;
}
else
{
Query[id].ans1 = Query[id].ans2 = ;
Query[id].ans2 += *sum1(X-)+sum1(t)-sum1(X);
Query[id].ans1 += sum2(X-);
Query[id].ans2 += *sum2(X-)+sum2(t)-sum2(X);
}
}
if(next[u][]== && next[u][]==)return;
add1(mp[w[u]],);
dfs(next[u][]);
add1(mp[w[u]],-);
add2(mp[w[u]],);
dfs(next[u][]);
add2(mp[w[u]],-);
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
int m;
int u,x,y;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i = ;i <= n;i++)
{
used[i] = false;
next[i][] = next[i][] = ;
vec[i].clear();
}
t = ;
for(int i = ;i <= n;i++)
{
scanf("%d",&w[i]);
a[t++] = w[i];
}
scanf("%d",&m);
while(m--)
{
scanf("%d%d%d",&u,&x,&y);
used[x] = true;
used[y] = true;
next[u][] = x;
next[u][] = y;
}
scanf("%d",&m);
for(int i = ;i < m;i++)
{
scanf("%d%d",&u,&x);
Query[i].v = u;
Query[i].X = x;
a[t++] = x;
vec[u].push_back(i);
}
for(int i = ;i <= n;i++)
if(!used[i])
{
root = i;
break;
}
sort(a,a+t);
t = unique(a,a+t)-a;
mp.clear();
for(int i = ;i < t;i++)
mp[a[i]]=i+;
memset(c1,,sizeof(c1));
memset(c2,,sizeof(c2));
dfs(root);
for(int i = ;i < m;i++)
{
if(Query[i].ans1 == -)
printf("0\n");
else printf("%d %d\n",Query[i].ans1,Query[i].ans2);
}
}
return ;
}

HDU 4602 Magic Ball Game(离线处理,树状数组,dfs)的更多相关文章

  1. 【loj6041】「雅礼集训 2017 Day7」事情的相似度 后缀自动机+STL-set+启发式合并+离线+扫描线+树状数组

    题目描述 给你一个长度为 $n$ 的01串,$m$ 次询问,每次询问给出 $l$ .$r$ ,求从 $[l,r]$ 中选出两个不同的前缀的最长公共后缀长度的最大值. $n,m\le 10^5$ 题解 ...

  2. 【bzoj4540】[Hnoi2016]序列 单调栈+离线+扫描线+树状数组区间修改区间查询

    题目描述 给出一个序列,多次询问一个区间的所有子区间最小值之和. 输入 输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数.接下来一行,包含n个整数,以空格隔开,第i个整数为ai,即序列第i ...

  3. hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点)

    hdu 6200 mustedge mustedge(并查集+树状数组 或者 LCT 缩点) 题意: 给一张无向连通图,有两种操作 1 u v 加一条边(u,v) 2 u v 计算u到v路径上桥的个数 ...

  4. 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序

    [题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...

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

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

  6. hdu 1556:Color the ball(第二类树状数组 —— 区间更新,点求和)

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  7. HDU 4746 莫比乌斯反演+离线查询+树状数组

    题目大意: 一个数字组成一堆素因子的乘积,如果一个数字的素因子个数(同样的素因子也要多次计数)小于等于P,那么就称这个数是P的幸运数 多次询问1<=x<=n,1<=y<=m,P ...

  8. HDU 4638 Group (2013多校4 1007 离线处理+树状数组)

    Group Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  9. hdu-3333 Turing Tree 离线区间+树状数组(区间不同数的和)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3333 题目大意: 给出一数组,以及m个查询区间,每次查询该区间不同数字的和.相同数字只加一次. 解题 ...

随机推荐

  1. CSS处理溢出

    如果内容超过的区块的大小,内容就会溢出,可以使用下面的方法控制溢出 overflow visible 不剪切内容也不添加滚动条 auto 在必需时对象内容才会被裁切或显示滚动条 hidden 不显示超 ...

  2. laravel中的$request对象构造及请求生命周期

    laravel应用程序中index.php是所有请求的入口.当用户提交一个form或者访问一个网页时,首先由kernel捕捉到该session PHP运行环境下的用户数据, 生成一个request对象 ...

  3. python——no module named XX

    加PYTHONPATH吧,新建一个系统环境变量,把你的目录复制进去即可

  4. bzoj4026

    直接按照欧拉函数的计算方式来即可 φ=区间积*区间出现(质数-1)的积/区间出现过的质数的积 区间积是满足类似区间减法的操作的(利用逆元) 由于强制在线,上主席树就可以了(维护每个质数上次出现的位置p ...

  5. 【笨嘴拙舌WINDOWS】剪切板

    Windows剪贴板是一种比较简单同时也是开销比较小的IPC(InterProcess Communication,进程间通讯)机制.Windows系统支持剪贴板IPC的基本机制是由系统预留的一块全局 ...

  6. AIX 第2章 指令记录

    root@db:/#mount  node       mounted        mounted over    vfs       date        options     ------- ...

  7. 用Python抓网页的注意事项

    用Python编一个抓网页的程序是非常快的,下面就是一个例子: import urllib2 html = urllib2.urlopen('http://blog.raphaelzhang.com' ...

  8. phonegap 百度云推

    1 创建新工程 -----获取api key 和secret key 2,推送设置 3,新建安卓项目,并把应用包名 和 推送中设置的包名设置一致 4,下载百度云客户端sdk 5,解压,并添加libs文 ...

  9. 【转】JavaSript模块规范 - AMD规范与CMD规范介绍

    JavaSript模块化   在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发?       模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问题 ...

  10. 对话框式Activity的设置

    <activity android:name=".OtherActivity" android:label="@string/app_name" andr ...