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 ...
随机推荐
- js生成唯一值的函数
利用了js的闭包性质 var uniqueNumber = (( function(){ var value = 0; return function(){ return ++value; }; }) ...
- Apache CXF实现Web Service(1)——不借助重量级Web容器和Spring实现一个纯的JAX-WS web service
废话少说,先在Eclipse中新建一个Java Project (可以不是WTP的Dynamic Web Project) 选择Java Project 再看pom.xml 我们使用cxf 3.1.4 ...
- JavaScript js 精确、保留小数方法
//保留两位小数 //功能:将浮点数四舍五入,取小数点后2位 function toDecimal(x) { var f = parseFloat(x); if (isNaN(f)) { return ...
- JavaScript 性能分析新工具 OneProfile
OneProfile 是一个网页版的小工具,可以用全新的方式展示 JavaScript 性能分析的结果,帮助开发者洞悉函数调用关系,优化应用性能. 点击打开 OneProfile 背景 Chrome ...
- ios下最简单的正则,RegexKitLite
ios下最简单的正则,RegexKitLite 1.去RegexKitLite下载类库,解压出来会有一个例子包及2个文件,其实用到的就这2个文件,添加到工程中.备用地址:http://www.coco ...
- ExtJs之Ext.isEmpty
<!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...
- C 和C++ 名称修饰规则
C名称修饰规则 1.对于使用__cdecl调用约定的函数,在函数名称前加一下划线,不考虑参数和返回值. 2.对于使用__fastcall调用约定的函数,在函数名称前后各加一@符号,后跟参数的长度,不考 ...
- Servlet3.0-使用注解定义Servlet
我使用的开发环境:MyEclipse10+Tomcat7+JDK6. 开发Servlet3的程序需要一定的环境支持.Servlet3是Java EE6规范的一部分,MyEclipse10和Tomcat ...
- CF A. Xenia and Divisors
题目大意: n(为三的倍数)个数的一个序列(每个数均不大于7),找出a,b,c a能被b整除,b能被c整除,序列中的每个数都被用到. 1 2 3 4 5 6 7 只有 1 2 4 1 2 6 1 3 ...
- 实现Web上的用户登录功能
关于如何实现web上的自动登录功能 文章来源http://coolshell.cn/articles/5353.html Web上的用户登录功能应该是最基本的功能了,可是在我看过一些站点的用户登录功能 ...