题意:给你一颗有根树,它的孩子要么只有两个,要么没有,且每个点都有一个权值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. Redis模式匹配删除key

    Redis keys命令支持模式匹配,但是del命令不支持模式匹配,有时候需要根据一定的模式来模糊删除key,这时只能结合shell命令来完成了. 具体命令是: redis-cli KEYS &quo ...

  2. Zabbix性能优化

    前言 如果不做表分区和删除历史数据规则设置的话,随着时间的推移zabbix的查询性能会变得很低 查看zabbix的性能 通过zabbix的NVPS(每秒处理数值数)来衡量其性能,在zabbix的das ...

  3. php判断中文,英文, 数字

    exeg Warning  This function was DEPRECATED in PHP 5.3.0, and REMOVED in PHP 7.0.0. function checkStr ...

  4. Github上fork了别人的项目之后如何同步代码

    其实很简单,如下: fork了别人代码到自己仓库,然后把自己仓库的代码clone下来 在本地添加远程仓库添加fork的代码库,git remote add xxx url git pull xxx m ...

  5. HDU1086You can Solve a Geometry Problem too(判断线段相交)

    You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/3 ...

  6. Web Service 中返回DataSet结果大小改进

    http://www.cnblogs.com/scottckt/archive/2012/11/10/2764496.html Web Service 中返回DataSet结果方法: 1)直接返回Da ...

  7. WebUploader UEditor chrome 点击上传文件选择框会延迟几秒才会显示 反应很慢

    chrome52.0.2743.80以上, accept: { title: 'Images', extensions: 'jpg,jpeg,png', mimeTypes: 'image/*' } ...

  8. SDL鼠标事件

    鼠标事件有这么多种,手柄的可以忽视,Sdl.SDL_KEYDOWN,Sdl.SDL_KEYUP,Sdl.SDL_MOUSEMOTION,Sdl.SDL_MOUSEBUTTONDOWN,Sdl.SDL_ ...

  9. JVM大端判断

    JVM采用大端方式存多字节的数据,判断方法如下: public static void bytesToInt() throws IOException { /** * 将字节数组(byte[])转为整 ...

  10. QT中使用函数指针

    想仿命令行,所以定义了一个类,让一个String 对应一个 function,将两者输入list容器. 类中定义了 QString commandStr; void (MainWindow::*com ...