HDU4605 Magic Ball Game

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

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

2013 Multi-University Training Contest 1

主席树。中序遍历,按顺序将节点建树。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <cstdio>
  6 const int N = 100000 + 3 ;
  7 using namespace std;
  8 int t,n,m,q,w[N],li[N],tot,root[N],roots,cnt;
  9 bool ru[N];
 10 struct id
 11 {
 12     int lson,rson;
 13 } id_tree[N];
 14 struct seg
 15 {
 16     int l,r,sum[2];//0 -> left_sum ; 1 -> right_sum
 17 }tree[N*30];
 18
 19 void Init( )
 20 {
 21     scanf("%d",&n);
 22     for(int i = 1;i <= n; ++i)
 23     {
 24         scanf("%d",w+i);
 25         li[i] = w[i];
 26     }
 27     sort(li+1,li+1+n); tot = 1;
 28     for(int i = 2; i <= n; ++i) if(li[i] != li[tot]) li[++tot] = li[i];
 29     scanf("%d",&m); int a,u,v;
 30     memset(id_tree,0,sizeof(id_tree));
 31     memset(ru,0,sizeof(ru));
 32     for(int i = 1; i <= m; ++i)
 33     {
 34         scanf("%d%d%d",&a,&u,&v);
 35         id_tree[a].lson = u , id_tree[a].rson = v;
 36         ru[u] = true , ru[v] = true;
 37     }
 38     for( int i = 1; i <= n; ++i )
 39     {
 40         if(ru[i] == false)
 41         {
 42             roots = i;
 43             break;
 44         }
 45     }
 46 }
 47
 48 int binary_search( int num )
 49 {
 50     int l = 1 , r = tot,ret = tot+1;
 51     while( l <= r )
 52     {
 53         int mid = l + ((r-l)>>1);
 54         if( li[mid] == num ) return mid;
 55         if( li[mid] < num ) l = mid + 1 ;
 56         else r = mid - 1 , ret = min(tot,mid);
 57     }
 58     return ret;
 59 }
 60
 61
 62 void updata(int l,int r,int &x,int y,int pos,int id)
 63 {
 64     tree[++cnt] = tree[y] ; x = cnt; ++tree[cnt].sum[id];
 65     if( l == r ) return;
 66     int mid = l + ((r-l)>>1) ;
 67     if( pos <= mid ) updata(l,mid,tree[x].l,tree[y].l,pos,id);
 68     else updata(mid+1,r,tree[x].r,tree[y].r,pos,id);
 69 }
 70
 71 void dfs(int u)
 72 {
 73     int l = id_tree[u].lson , r = id_tree[u].rson;
 74     if(l == r && r == 0) return;
 75     int add = binary_search( w[u] );
 76     updata(1,tot,root[l],root[u],add,0);
 77     dfs( l );
 78     updata(1,tot,root[r],root[u],add,1);
 79     dfs( r );
 80 }
 81
 82
 83 int query(int l,int r,int num,int L,int R,int id)
 84 {
 85     if( L > R ) return 0;
 86     if( l == L && r == R ) return tree[num].sum[id];
 87     int mid =l + ((r-l)>>1);
 88     if( R <= mid ) return query(l,mid,tree[num].l,L,R,id);
 89     else if( L > mid ) return query(mid+1,r,tree[num].r,L,R,id);
 90     return query(l,mid,tree[num].l,L,mid,id) + query(mid+1,r,tree[num].r,mid+1,R,id);
 91 }
 92
 93
 94 void Solve( )
 95 {
 96     memset(tree,0,sizeof(tree)); cnt = 0;
 97     dfs( roots ) ;
 98     scanf("%d",&q);
 99     int v,X;
100     while(q--)
101     {
102         scanf("%d%d",&v,&X);
103         if( v == 1 )
104         {
105             printf("0 0\n");
106             continue;
107         }
108         int r = binary_search( X ) ; int l = r - 1;
109         if( li[r] == X )
110         {
111             if(query(1,tot,root[v],r,r,0) + query(1,tot,root[v],r,r,1) > 0)
112             {
113                 puts("0") ;
114                 continue ;
115             }
116         }
117         int r_less = query(1,tot,root[v],1,l,1), r_more = query(1,tot,root[v],r,tot,1);
118         int l_less = query(1,tot,root[v],1,l,0), l_more = query(1,tot,root[v],r,tot,0);
119         int x = r_less, y = 3*(r_less + l_less) + r_more + l_more;
120
121         printf("%d %d\n",x,y);
122     }
123 }
124
125 int main()
126 {
127     scanf("%d",&t);
128     while(t--)
129     {
130         Init();
131         Solve();
132     }
133     fclose(stdin);
134     fclose(stdout);
135     return 0;
136 }
时间: 2024-10-08 18:51:50

HDU4605 Magic Ball Game的相关文章

hdu4605 Magic Ball Game(树状数组)

题目链接:点这里!!!! 题意: 给定一棵N(N<=1e5)节点的树,每个节点要么有两个儿子(左右两个儿子),要么没有儿子,每个节点有一个权值w[i]. 一个权值为X球从根节点开始下落,每落到一个节点的时候, 1.如果X=W[i],或者没有儿子节点了,球停止下落. 2.如果X<W[i],球各有1/2的概率落到左右儿子节点. 3.如果X>W[i],球有1/8的概率落到左儿子,有7/8的概率落到右儿子. 给你q(q<=1e5)个询问,询问中包含v,x.问你权值为x的球从根节点(根节点是

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

hdu 4605 题意: 有一颗树,根节点为1,每一个节点要么有两个子节点,要么没有,每个节点都有一个权值wi .然后,有一个球,附带值x . 球到达某个节点上,如果x==wi,那么球停在这个节点上 .当然,这个点是叶子节点也会停止 . 如果x<wi,那么有1/2的概率走向左子树,有1/2的概率走向右子树 . 如果x>wi,那么有1/8的概率走向左子树,有7/8的概率走向右子树 . 问球经过v节点的概率 .(停在v节点也算) 解法: 在线的话每一个节点建一棵根节点到该节点的线段树,离线的话就先

【HDOJ】4605 Magic Ball Game

思路1:树状数组+离线处理,对所有的w离散化处理,边dfs边使用树状数组更新左右w的情况.思路2:主席树,边bfs边建树.结点信息存储cnt,然后在线查询.树状数组. 1 /* 4605 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #inc

HDU 5125 Magic Ball DP+树状数组

由于只要找1~x 中的最大值,然后线段树又容易MLE,所以这里可以用树状数组搞. #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <set> #include <bitset> #include <queue> #include <stack> #include <string> #i

hdu 3717 Rescue

Rescue Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 708    Accepted Submission(s): 167 Problem Description The princess is trapped in a magic place. In this place, there are N magic stones. I

线段树题目总结

一.单点更新 1.hdu1166 敌兵布阵:有N个兵营,每个兵营都给出了人数ai(下标从1开始),有四种命令,(1)"Addij",表示第i个营地增加j人.(2)"Sub i j",表示第i个营地减少j人.(3)"Query ij",查询第i个营地到第j个营地的总人数.(4)"End",表示命令结束.解题报告Here. 2.hdu1754 I Hate It:给你N个数,M个操作,操作分两类.(1)"QAB"

线段树总结 (转载 里面有扫描线类 还有NotOnlySuccess线段树大神的地址)

转载自:http://blog.csdn.net/shiqi_614/article/details/8228102 之前做了些线段树相关的题目,开学一段时间后,想着把它整理下,完成了大牛NotOnlySuccess的博文“完全版线段树”里的大部分题目,其博文地址Here,然后也加入了自己做过的一些题目.整理时,更新了之前的代码风格,不过旧的代码仍然保留着. 同样分成四类,不好归到前四类的都分到了其他.树状数组能做,线段树都能做(如果是内存限制例外),所以也有些树状数组的题目,会标示出来,并且放

树状数组详解(图形学算法)

目录 一.从图形学算法说起 1.Median Filter 概述 2.r pixel-Median Filter 算法 3.一维模型 4.数据结构的设计 5.树状数组华丽登场 二.细说树状数组 1.树 or 数组? 2.结点的含义 3.求和操作 4.更新操作 5.lowbit函数O(1)实现 6.小结 三.树状数组的经典模型 1.PUIQ模型 2.IUPQ模型 3.逆序模型 4.二分模型 5.再说Median Filter 6.多维树状数组模型 四.树状数组题集整理 一.从图形学算法说起 1.M

hdu 3717 Rescue 二分加队列优化(技巧)

Rescue Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 814    Accepted Submission(s): 198 Problem Description The princess is trapped in a magic place. In this place, there are N magic stones.