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. Ubuntu中文输入法的安装

    Ubuntu上的输入法主要有小小输入平台(支持拼音/二笔/五笔等),Fcitx,Ibus,Scim等.其中Scim和Ibus是输入法框架. 在Ubuntu的中文系统中自带了中文输入法,通过Ctrl+S ...

  2. HDU 3666 THE MATRIX PROBLEM (差分约束,最短路)

    题意: 给一个n*m矩阵,每个格子上有一个数字a[i][j],给定L和U,问:是否有这样两个序列{a1...an}和{b1...bn},满足 L<=a[i][j]*ai/bj<=U .若存 ...

  3. 【英语】Bingo口语笔记(64) - Beat系列

  4. MySQL常用的操作整理

    MySQL是一个十分轻便的dbms,轻便.灵活,更适用于中小型数据的存储与架构.MySQL被数以万计的网站采用,从5版本以后,陆续支持了游标.触发器.事务.存储过程等高级应用,这也给MySQL的易用性 ...

  5. NodeJS模块

    node> module { id: 'repl', exports: { writer: { [Function: inspect] colors: [Object], styles: [Ob ...

  6. hdu 2516(斐波拉切博弈)

    题意:容易理解. 分析:通过枚举寻找规律,这就是做1堆或者2堆石子博弈的技巧!当为2或者3时,肯定是第二个人赢,当为4时,先去一个石子,然后当对方面临3,于是第一个人赢, 当为5时,取1时,第二个人赢 ...

  7. ArcGIS 开发的一些知识学习点

    由于文章太多,不便转载,现主要列举如下: ArcGIS Runtime支持的GP工具列表 ArcGIS Runtime支持的GP工具列表 目录(?)[-] Standard版本Standard 空间分 ...

  8. 怎样学法学?——民法学泰斗王利明教授的演讲 z

    今晚我讲“怎样学习法律”,但不是讲一般的学习法学的方法,而是主要从法学.法律的特征讲起.(因为)我们学习任何东西,都首先要搞清楚我们的学习对象有什么特征.性质. 我们要了解法律.法学本身的性质,要了解 ...

  9. [转]Linux关机命令详解

    转自:http://www.jb51.net/os/RedHat/1334.html linux下常用的关机命令有:shutdown.halt.poweroff.init:重启命令有:reboot.下 ...

  10. CSS的优先级规则

    CSS的优先级规则有两类 1.位置群组规则 最高优先级为元素内嵌的style样式,如<div style=” “></div> 次高优先级为html头部中的<style& ...