题意:给你一棵二叉树,每个节点有一个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 树状数组+离线处理的更多相关文章

  1. HDU-4605 Magic Ball Game 树状数组+离散+dfs

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4605 题意:给一颗树,每个节点有个权值w[u],每个节点只有两个儿子或者没有儿子,从根节点放下一个小球 ...

  2. HDU 4605 Magic Ball Game 树状数组

    题目大意很简单. 有一颗树(10^5结点),所有结点要么没有子结点,要么有两个子结点.然后每个结点都有一个重量值,根结点是1 然后有一个球,从结点1开始往子孙结点走. 每碰到一个结点,有三种情况 如果 ...

  3. Necklace HDU - 3874 (线段树/树状数组 + 离线处理)

    Necklace HDU - 3874  Mery has a beautiful necklace. The necklace is made up of N magic balls. Each b ...

  4. 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]< ...

  5. SPOJ DQUERY树状数组离线or主席树

    D-query Time Limit: 227MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Submit Status ...

  6. D-query SPOJ 树状数组+离线

    D-query SPOJ 树状数组+离线/莫队算法 题意 有一串正数,求一定区间中有多少个不同的数 解题思路--树状数组 说明一下,树状数组开始全部是零. 首先,我们存下所有需要查询的区间,然后根据右 ...

  7. BZOJ1878: [SDOI2009]HH的项链[树状数组 离线]

    1878: [SDOI2009]HH的项链 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 3486  Solved: 1738[Submit][Statu ...

  8. HD1556Color the ball(树状数组)

    Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  9. HDU3333 Turing Tree 树状数组+离线处理

    Turing Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. js函数延迟执行

    function delay(value){ //全局变量保存当前值 window._myTempDalayValue = value; setTimeout(function(){ //延时之后与全 ...

  2. 迁移到MariaDB galera

    迁移到MariaDB galera [已注销] [已注销] -- :: [安装] ====== https://downloads.mariadb.org/mariadb/repositories/ ...

  3. hdu 4725

    The Shortest Path in Nya Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  4. POJ 1986 Distance Queries (最近公共祖先,tarjan)

    本题目输入格式同1984,这里的数据范围坑死我了!!!1984上的题目说边数m的范围40000,因为双向边,我开了80000+的大小,却RE.后来果断尝试下开了400000的大小,AC.题意:给出n个 ...

  5. editplus的各式插件

    C/C++, Java, JSP, C#, .NET, SQL, Pascal, Python, Assembly, Basic files http://www.editplus.com/javac ...

  6. C# JSON字符串序列化与反序列化

    JSON与c#对象转换http://hi.baidu.com/donick/item/4d741338870c91fe97f88d33 C# JSON字符串序列化与反序列化 – http://www. ...

  7. ExtJs之Ext.form.field.ComboBox组合框

    <!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...

  8. (4)opencv在android平台上实现 物体跟踪

    最近项目时间很紧,抓紧时间集中精力去研究android平台的opencv里的物体跟踪技术 其他几篇文章有时间再去完善吧 从网上找到了一些实例代码,我想采取的学习方法是研究实例代码和看教程相结合,教程是 ...

  9. BZOJ 2424: [HAOI2010]订货 费用流

    2424: [HAOI2010]订货 Description 某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定第一月月 ...

  10. (转载)怎么写tab?

    演示地址:http://www.adanghome.com/js_demo/3/ =========================================================== ...