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 ...
随机推荐
- pyhton Chapter3 读文件
使用内置函数open()打开文件,data=open("1.txt").利用data.close()关闭文件.利用data.readline()读取文件中的一行数据,然后指示读取文 ...
- SEO优化的黑帽手法是否值得使用?
PR劫持 可能很多人也会听到说,什么网站权重越高越好,这也就是后面越来越多人都对谷歌的PR的宣传看的很重,自建站的都追求PR值,权重越高代表这个网站越受信任. 比如一个新站PR值为0,一个老站PR为6 ...
- vi/vim使用指北 ---- Sample Editing
本篇介绍vim的基础操作,各种编辑模式的切换,光标的移动,删除,撤销/重做,保存,查找等基础命令: 基础操作 编辑文件 vim [options] [file ...] 模式 打开文件后进入vim的 ...
- Linux :Can't start up: not enough memory
http://stackoverflow.com/questions/9634577/linux-cant-start-up-not-enough-memory
- JavaScript. The core.
Read this article in: Japanese, German (version 2), Arabic, Russian, French, Chinese. An object A pr ...
- 知问前端——对话框UI(一)
对话框(dialog),是jQuery UI非常重要的一个功能.它彻底的代替了JavaScript的alert().prompt()等方法,也避免了新窗口或页面的繁杂冗余. 开启多个dialog 我们 ...
- Struts2 Convention插件的使用(3)方法前的@Action注解
package com.hyy.action; import org.apache.struts2.convention.annotation.Action; import com.opensymph ...
- 几个经常用到的字符串的截取(java)
几个经常用到的字符串的截取 string str="123abc456";int i=3;1 取字符串的前i个字符 str=str.Substring(0,i); // or ...
- HTTP协议中TCP的三次握手,四次挥手总结
建立TCP需要三次握手才能建立,而断开连接则需要四次挥手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...
- RHadoop计算平台搭建
原创文章,转载请注明: 转载自www.cnblogs.com/tovin/p/3824554.html 本文基于CentOS6.4系统介绍基于RHadoop平台的搭建,Hadoop的搭建可以参考ht ...