hdu4605 magic ball game 树状数组+离线处理
题意:给你一棵二叉树,每个节点有一个w值,现在有一颗小球,值为x,从根节点往下掉,如果w==x,那么它就会停止;如果w>x,那么它往左、右儿子的概率都是1、2;如果w<x,那么它往左儿子的概率是1/8,右儿子是7/8。现在给你q个询问,问你值为x的球道达节点u的概率为多少。
连接:http://acm.hdu.edu.cn/showproblem.php?pid=4605
思路:节点和询问比较多,可以储存询问集中处理。将所有的询问集中起来,与被询问的节点放在一起一起走,让所有节点的W值与被询问的W值都存起来排序,这样走过的节点设置为1没走过的为0这样就可以知道谁比他大谁比他小,另外设两个数组就可以知道是走了右边还是左边,这样线段树和树状数组都可以求解。
用宝哥的话说最后的答案就是:从一根节点u到一个点v存在的是唯一的一条确定的道路。我们只需要它在这条路上往左拐的情况中w的值(X可能大于该点的权值grtL,可能小于该点的权值lessL) 往右拐的情况中w的值(X可能大于该点的权值grtR,可能小于该点的权值lessR) 那么对于这个点的询问我们就可以知道:
x = grtR(只有它对7有贡献) y = (lessL + lessR) + (grtL + grtR)*3;
代码:(用g++ac,叫c++的话加上 #pragma comment(linker, "/STACK:1024000000,1024000000")
注意离散处理一下,让bsearch中不会出现相同的值,假设好多树节点的值相同,只需要+1即可。树状数组存的就是出现次数。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <queue>
#include <vector>
#define cl(a,b) memset(a,b,sizeof(a))
#define loop(s,i,n) for(i = s;i < n;i++) const int maxn = ;
using namespace std;
struct ask
{
int num,turn;
};
struct node
{
int num,l,r;
}g[maxn];
int a[maxn*];
int b[maxn*];
int num[maxn*];
int suml[maxn*];
int sumr[maxn*];
vector<ask>q[maxn];
int ans[maxn][];
int cnt;
int lowbit(int x)
{
return x&-x;
}
int sumleft(int x)
{
int ret;
ret = ;
while(x > )
{
ret += suml[x];
x-= lowbit(x);
}
return ret;
} int sumright(int x)
{
int ret;
ret = ;
while(x > )
{
ret += sumr[x];
x-= lowbit(x);
}
return ret;
}
void addl(int x,int d)
{
while(x <= cnt)
{
suml[x] += d;
x += lowbit(x);
}
} void addr(int x,int d)
{
while(x <= cnt)
{
sumr[x] += d;
x += lowbit(x);
}
}
int bsearch(int key)
{
int l,r,mid;
l = ;
r = cnt;
while(l <= r)
{
mid = (l+r)/;
if(b[mid] == key) return mid;
if(key < b[mid]) r = mid-;
else l = mid+;
}
return ;
}
void dfs(int rt)
{
int i;
int t,loc;
for(i = ;i < q[rt].size();i++)
{ t = q[rt][i].num;
loc = bsearch(t);
if(a[loc] > )
{
ans[q[rt][i].turn][] = -;
ans[q[rt][i].turn][] = -; }
else{
ans[q[rt][i].turn][] = sumright(loc);
ans[q[rt][i].turn][] = *sumleft(loc)+sumleft(cnt)-sumleft(loc)+*sumright(loc)+sumright(cnt)-sumright(loc);
} }
loc = bsearch(g[rt].num);
if(g[rt].l)
{
addl(loc,);
a[loc]++;
dfs(g[rt].l);
addl(loc,-);
a[loc]--;
}
if(g[rt].r){
addr(loc,);
a[loc]++;
dfs(g[rt].r);
addr(loc,-);
a[loc]--;
}
return ; }
int main()
{
int t;
cin>>t;
while(t--)
{
int m,n;
scanf("%d",&n);
cnt = ;
int i;
memset(sumr,,sizeof(sumr));
cl(suml,);
cl(a,); loop(,i,n+)
scanf("%d",&g[i].num),g[i].l = g[i].r = ,num[cnt] = g[i].num,cnt++,q[i].clear(); scanf("%d",&m);
while(m--)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
g[a].l = b;
g[a].r = c;
}
int k;
scanf("%d",&k);
loop(,i,k+)
{
int tmp,w;
scanf("%d %d",&tmp,&w);
struct ask temp;
temp.num = w;
temp.turn = i;
q[tmp].push_back(temp);
num[cnt++] = w;
}
cnt--; sort(num+,num+cnt+);
int zcnt;
zcnt = ;
num[] = ;
for(i = ;i <= cnt;i++)
{
if(num[i] != num[i-])
b[++zcnt] = num[i];
}
cnt = zcnt;
dfs();
for(i = ;i <= k;i++)
{
if(ans[i][] == - || ans[i][] == -)
{
puts("");
continue;
}
else
{
printf("%d %d\n",ans[i][],ans[i][]);
} } }
return ;
}
hdu4605 magic ball game 树状数组+离线处理的更多相关文章
- HDU-4605 Magic Ball Game 树状数组+离散+dfs
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4605 题意:给一颗树,每个节点有个权值w[u],每个节点只有两个儿子或者没有儿子,从根节点放下一个小球 ...
- HDU 4605 Magic Ball Game 树状数组
题目大意很简单. 有一颗树(10^5结点),所有结点要么没有子结点,要么有两个子结点.然后每个结点都有一个重量值,根结点是1 然后有一个球,从结点1开始往子孙结点走. 每碰到一个结点,有三种情况 如果 ...
- Necklace HDU - 3874 (线段树/树状数组 + 离线处理)
Necklace HDU - 3874 Mery has a beautiful necklace. The necklace is made up of N magic balls. Each b ...
- 2016 Multi-University Training Contest 5 1012 World is Exploding 树状数组+离线化
http://acm.hdu.edu.cn/showproblem.php?pid=5792 1012 World is Exploding 题意:选四个数,满足a<b and A[a]< ...
- SPOJ DQUERY树状数组离线or主席树
D-query Time Limit: 227MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submit Status ...
- D-query SPOJ 树状数组+离线
D-query SPOJ 树状数组+离线/莫队算法 题意 有一串正数,求一定区间中有多少个不同的数 解题思路--树状数组 说明一下,树状数组开始全部是零. 首先,我们存下所有需要查询的区间,然后根据右 ...
- BZOJ1878: [SDOI2009]HH的项链[树状数组 离线]
1878: [SDOI2009]HH的项链 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 3486 Solved: 1738[Submit][Statu ...
- HD1556Color the ball(树状数组)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- HDU3333 Turing Tree 树状数组+离线处理
Turing Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
随机推荐
- 关于iOS7 上下黑条解决办法
解决办法 找到工程的targest->General->Launch Image Sourse OK 运行问题解决
- POJ 2140
#include<iostream> #include<stdio.h> using namespace std; int main() { int num; int i; i ...
- PHP使用SOAP调用.net的WebService数据
需要和一个.net系统进行数据交换,对方提供了一个WebService接口,使用PHP如何调用这个数据呢,下面就看看使用SOAP调用的方法吧 这个与一般的PHP POST或GET传值再查库拿数据的思路 ...
- HDU 5596/BestCoder Round #66 (div.2) GTW likes math 签到
GTW likes math Memory Limit: 131072/131072 K (Java/Others) 问题描述 某一天,GTW听了数学特级教师金龙鱼的课之后,开始做数学<从自主 ...
- 初始BOM
1.BOM(Browser Object Model),定义了操作浏览器的借口 2.常用的BOM对象:Window, History,Navigator,Screen, Location等 3.由于浏 ...
- php 修改 AppServ 下Apache 端口
php 修改 AppServ 下Apache 端口 步骤一:把 C:\AppServ\Apache2.2\conf 中httpd.conf修改了 还不正确 步骤二:把httpd.conf 中List ...
- 李洪强iOS开发之- 实现简单的弹窗
李洪强iOS开发之- 实现简单的弹窗 实现的效果: 112222222222223333333333333333
- eclipse工程设置的问题
- JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-003使用@AttributeOverrides
Each @AttributeOverride for a component property is “complete”: any JPA or Hibernate annotation on t ...
- Java笔记——JavaMail发送邮件
1.JavaMail概述 Java Mail是由SUN公司提供的专门针对邮件的API,主要Jar包:mail.jar.activation.jar. ======================== ...