题意:给你一颗有根树,它的孩子要么只有两个,要么没有,且每个点都有一个权值w。

接着给你一个权值为x的球,它从更节点开始向下掉,有三种情况

x=w[now]:停在此点

x<w[now]:当有孩子时:1/2可能性到左孩子,1/2可能性到右孩子

x>w[now]:当有孩子时:1/8可能性到左孩子,7/8可能性到右孩子

再给你一个点U,问你从根节点到U结点的可能性为多少 7^x/2^y ,求出x y

题解:非常经典的一个题,我使用邻接表存储,接着使用dfs遍历,最后树状数组维护结果。

我们可以知道    1/2:y++        1/8:y+=3     7/8:x++,y+=3

接着就是每次只需要找到唯一一条从根到U点父节点的所有权值

接着找:左孩子中小于X的个数,右孩子中小于X的个数,左孩子中大于X的个数,右孩子中大于X的个数,但是我们要注意一个情况就是当有等于X的时候就不能到达U

这样我们可以离线vector存储问题(同一个点不同则存在一起),从根节点开始dfs遍历每个点

当走孩子节点时就把此点的权值加入数组(开两个数组),回溯时删除此权值

在添加前就此点权值寻找上诉四个值,并利用树状数组维护

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const double Pi=acos(-1.0);
const int Mod=1e9+;
const int Max=;//包括询问
int head[Max],nnext[Max],to[Max],chi[Max],e;//邻接表存树 dfs遍历
struct node
{
int val,poi;
} que[Max]; //问题
int dir[][]= {{,},{,},{,}}; //比x大的孩子 比x小的左孩子 比x小的右孩子
map<int,int> mp;//离散化
int val[Max];
vector<int> vec[Max];//存下这个点有哪些权值
int len[Max],ansx[Max],ansy[Max];
int nn;//总权值点
void Init(int n,int *lbit,int *rbit)
{
for(int i=; i<=n; ++i)
{
len[i]=;
ansx[i]=;
ansy[i]=;
head[i]=-;
vec[i].clear();
}
e=;
nn=;
mp.clear();
memset(lbit,,sizeof(lbit));
memset(rbit,,sizeof(rbit));
return;
}
void AddEdge(int u,int v,int ch)
{
nnext[e]=head[u];
to[e]=v;
chi[e]=ch;
head[u]=e++;
return;
}
int lowbit(int x)
{
return x&(-x);
}
void Add(int x,int y,int *bit)
{
while(x<=nn)
{
bit[x]+=y;
x+=lowbit(x);
}
return;
}
int Sum(int x,int *bit)
{
int sum=;
while(x)
{
sum+=bit[x];
x-=lowbit(x);
}
return sum;
}
int bit[][Max];//区分左右孩子
void dfs(int son,int tol1,int tol2)//遍历邻接表
{
int now=mp[val[son]];
for(int i=; i<len[son]; ++i)
{
int now1=mp[que[vec[son][i]].val];
int lef1=Sum(now1,bit[]);
int lef2=Sum(now1-,bit[]);
int rig1=Sum(now1,bit[]);
int rig2=Sum(now1-,bit[]);
if(lef1-lef2||rig1-rig2)
{
ansx[vec[son][i]]=-;
}
else//求值
{
ansx[vec[son][i]]=rig2*dir[][]; ansy[vec[son][i]]=(tol1-lef1)*dir[][];
ansy[vec[son][i]]+=(tol2-rig1)*dir[][];
ansy[vec[son][i]]+=lef2*dir[][];
ansy[vec[son][i]]+=rig2*dir[][];
}
}
for(int i=head[son]; ~i; i=nnext[i])
{
Add(now,,bit[chi[i]]);//加点
if(!chi[i])
dfs(to[i],tol1+,tol2);
else
dfs(to[i],tol1,tol2+);
Add(now,-,bit[chi[i]]);//删点
}
return;
}
int main()
{
int t,n,m,q;
int u,a,b;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
Init(n,bit[],bit[]);
for(int i=; i<=n; ++i)
{
scanf("%d",&val[i]);
mp[val[i]]=;
}
scanf("%d",&m);
for(int i=; i<m; ++i)//邻接表
{
scanf("%d %d %d",&u,&a,&b);
AddEdge(u,a,);
AddEdge(u,b,);
}
scanf("%d",&q);
for(int i=; i<q; ++i)
{
scanf("%d %d",&que[i].poi,&que[i].val);
vec[que[i].poi].push_back(i);//根据树上某点存que小标
len[que[i].poi]++;
mp[que[i].val]=;
}
int cnt=;
for(map<int,int>::iterator it=mp.begin(); it!=mp.end(); ++it) //离散化
{
it->second=cnt++;
nn++;
}
dfs(,,);
for(int i=; i<q; ++i)
{
if(ansx[i]==-)
printf("0\n");
else
printf("%d %d\n",ansx[i],ansy[i]);
}
}
return ;
}

HDU 4605 Magic Ball Game (dfs+离线树状数组)的更多相关文章

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

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

  2. HDU 5603 the soldier of love 离线+树状数组

    这是bestcorder 67 div1 的1003 当时不会做 看了赛后官方题解,然后翻译了一下就过了,而且速度很快,膜拜官方题解.. 附上官方题解: the soldier of love 我们注 ...

  3. HDU 3887 Counting Offspring(DFS序+树状数组)

    Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  4. HDU 5869 Different GCD Subarray Query 离线+树状数组

    Different GCD Subarray Query Problem Description   This is a simple problem. The teacher gives Bob a ...

  5. HDU 4605 Magic Ball Game (在线主席树|| 离线 线段树)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意:给出一棵二叉树,每个结点孩子数目为0或者2. ...

  6. HDU 3887:Counting Offspring(DFS序+树状数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意:给出一个有根树,问对于每一个节点它的子树中有多少个节点的值是小于它的. 思路:这题和那道苹果树是一样 ...

  7. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

  8. HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...

  9. 【BZOJ3653】谈笑风生 离线+树状数组+DFS序

    [BZOJ3653]谈笑风生 Description 设T 为一棵有根树,我们做如下的定义: ? 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道高明到哪里去了”. ? 设a 和 ...

随机推荐

  1. nginx + mysql + php相关源码包及安装

    nginx + mysql + php安装 引言 完整的搭建一个nginx+php-fpm+mysql的服务器,一直是我向做的,不过一致没有完成过,这次工作需要,终于安装成功了 我列出了我遇到的一些问 ...

  2. Jquery ajax运用执行顺序有误怎么解决

    在这儿,可能就要提示一个ajax的一个属性async async默认的设置值为true,这种情况为异步方式,就是说当ajax发送请求后,在等待server端返回的这个过程中,前台会继续执行ajax块后 ...

  3. 分享:录制gif小图片工具

    今天博主分享一个录制gif小图片的工具[LICEcap]: 有的时候,图片解释起来不够直观,如果是一段小动画,别人一看就懂了. 工具我放在百度网盘上面,当然也可以自己在网上下载. 下载地址:http: ...

  4. mate标签

    <meta charset='utf-8'> <!-- 优先使用 IE 最新版本和 Chrome -->    <meta http-equiv="X-UA-C ...

  5. 简述block

    block传值也适用于从后往前传值 先介绍block的基本知识 /** * 1.如何定义一个Block变量 2.怎样给定义的Block变量赋初值 3.如何冲定义Block类型 4.如何使用Block实 ...

  6. Linux 等待进程结束 wait() 和 waitpid()

    若子进程先于父进程结束时,父进程调用wait()函数和不调用wait()函数会产生两种不同的结果: --> 如果父进程没有调用wait()和waitpid()函数,子进程就会进入僵死状态. -- ...

  7. C和指针 第十二章 使用结构和指针 双链表和语句提炼

    双链表中每个节点包含指向当前和之后节点的指针,插入节点到双链表中需要考虑四种情况: 1.插入到链表头部 2.插入到链表尾部 3.插入到空链表中 4.插入到链表内部 #include <stdio ...

  8. php实战开发之自我整理(学习笔记)

    PHP没有创建变量的命令,变量会在首次赋值时进行创建. 简单样例 1 <?php $word="My first choice"; $x=5; echo $x; echo & ...

  9. Python正则表达式详解

    我用双手成就你的梦想 python正则表达式 ^ 匹配开始 $ 匹配行尾 . 匹配出换行符以外的任何单个字符,使用-m选项允许其匹配换行符也是如此 [...] 匹配括号内任何当个字符(也有或的意思) ...

  10. python写计算器

    #!/usr/bin/env python # -*- coding:utf-8 -*- import re def chu(arg1): #定义加减 arg = arg1[0] #beacuse p ...