题意:一颗二叉树,任意节点要么有两个孩子要么没孩子。

然后有一个球,从结点1开始往子孙结点走。

每碰到一个结点,有三种情况

如果此球重量等于该结点重量,球就停下了

如果此球重量小于该结点重量,则分别往左右儿子走的可能都是1/2

如果此球重量大于该结点重量,则走向左儿子的概率是1/8,右儿子的概率是7/8

然后若干个询问(10^5次),问一个重量为x的球经过结点v的概率

观察路径,可以发现路径可以分成两种,向左走的路径和向右走的路径,分成这两种是因为各自的计算公式,在向左走的路径中,设大于x的点权有a个,小于x的点权有b个,同理定义c d,我们只需要求出a b c d 就可以了。

做法:

貌似很多做法,,我是用主席树多的,对于节点V,建立根节点1到V的前缀线段树,(此过程bfs实现)利用主席树的性质。

然后主席树里面存两个信息,一个是向左走的一个是向右走的。(此题一些细节,二分的时候不注意的话就会一直wa)

 #include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std; const int maxn = 1e5+;
struct Edge
{
int to,next,kind;
} e[maxn<<];
int head[maxn],edge_idx;
void add_edge(int x,int y,int kind)
{
e[edge_idx].to = y;
e[edge_idx].next = head[x];
e[edge_idx].kind = kind;
head[x] = edge_idx++;
}
//----------------------------------
int lcnt[maxn*],rcnt[maxn*],lson[maxn*],rson[maxn*];
int tree[maxn<<],tot,tree_max;
int build (int l,int r)
{
int root = tot++;
lcnt[root] = rcnt[root] = ;
if (l != r)
{
int mid = (l + r) >> ;
lson[root] = build(l,mid);
rson[root] = build(mid+,r);
}
return root;
}
int update (int root,int pos,int lval,int rval)
{
int newroot = tot++;
int tmp = newroot;
int l = ,r = tree_max;
lcnt[newroot] = lcnt[root] + lval;
rcnt[newroot] = rcnt[root] + rval;
while (l < r)
{
int mid = (l + r) >> ;
if (pos <= mid)
{
r = mid;
rson[newroot] = rson[root];
root = lson[root];
lson[newroot] = tot++;
newroot = lson[newroot];
}
else
{
l = mid + ;
lson[newroot] =lson[root];
root = rson[root];
rson[newroot] = tot++;
newroot = rson[newroot];
}
lcnt[newroot] = lcnt[root] + lval;
rcnt[newroot] = rcnt[root] + rval;
}
return tmp;
}
int query(int root,int l,int r,int ua,int ub,int kind)
{
if (ub < ua)
return ;
if (ua <= l && ub >= r)
{
if (kind)
return rcnt[root];
else
return lcnt[root];
}
int mid = (l + r) >> ;
int t1 = , t2 = ;
if (ua <= mid)
t1 = query(lson[root],l,mid,ua,ub,kind);
if (ub > mid)
t2 = query(rson[root],mid+,r,ua,ub,kind);
return t1 + t2;
} int W[maxn],vec[maxn],idx;
int hash_(int x)
{
return lower_bound(vec,vec+idx,x) - vec + ;
}
void init()
{
memset(head,-,sizeof(head));
idx = tot = ;
edge_idx = ;
}
int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int T;
scanf ("%d",&T);
while (T--)
{
init();
int n,q,m;
scanf ("%d",&n);
for (int i = ; i < n ; i++)
{
scanf ("%d",W+i+);
vec[idx++] = W[i+];
}
sort(vec,vec+idx);
idx = unique(vec,vec+idx) - vec;
scanf ("%d",&m);
for (int i = ; i < m; i++)
{
int x,lf,rg;
scanf ("%d%d%d",&x,&lf,&rg);
add_edge(x,lf,);
add_edge(x,rg,);
}
tree_max = n;
tree[] = build(,n); queue<int>Q;
while (!Q.empty())
Q.pop();
Q.push();
while (!Q.empty())
{
int x = Q.front();
Q.pop();
for (int i = head[x]; ~i; i = e[i].next)
{
int v,k;
v = e[i].to, k = e[i].kind;
tree[v] = update(tree[x],hash_(W[x]),k == , k == );
Q.push(v);
}
}
scanf ("%d",&q);
for (int i = ; i < q; i++)
{
int x,v;
scanf ("%d%d",&v,&x);
if (v == )
{
printf("0 0\n");
continue;
}
int tmp = x; //
x = hash_(x); // 二分得到的值可能原数组并不存在
int ua = x-, ub = x; //理论上要查询x+1,但是如果tmp在原数组中不存在,那么就不用+1了
int flag = ;
flag = query(tree[v],,n,x,x,) + query(tree[v],,n,x,x,);
if (vec[x-] == tmp)
{
if (flag)
{
printf("0\n");
continue;
}
ub++;
}
int lf_small = query(tree[v], , n, , ua, );
int lf_big = query(tree[v], , n, ub, n, );
int rg_small = query(tree[v], , n, , ua, );
int rg_big = query(tree[v], , n, ub, n, );
int ans1 = , ans2 = ;
ans1 += rg_small;
ans2 += *(rg_small+lf_small) + rg_big + lf_big;
printf("%d %d\n",ans1,ans2);
}
}
return ;
}

HDU4605---Magic Ball Game(主席树 好题)的更多相关文章

  1. HDU 4605 Magic Ball Game 主席树

    题意: 给一棵\(n(1 \leq n \leq 10^5)\)个节点的二叉树,除叶子节点外,每个点都有左儿子和右儿子. 每个点上都有一个权值. 游戏规则是这样的:在根节点放一个权值为\(X\)的小球 ...

  2. 【POJ 2104】 K-th Number 主席树模板题

    达神主席树讲解传送门:http://blog.csdn.net/dad3zz/article/details/50638026 2016-02-23:真的是模板题诶,主席树模板水过.今天新校网不好,没 ...

  3. BZOJ4408: [Fjoi 2016]神秘数【主席树好题】

    Description 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13}, 1 = 1 2 = 1+1 3 = 1+1+1 4 = 4 5 = ...

  4. poj2104 主席树模板题

    题意 给出n个数字组成的数字序列,有m组询问.每次询问包含三个数字l,r,k.对于每个询问输出序列区间[l,r]中第k大的数字. 分析 这是主席树的模板题,套板子就可以 #include <cs ...

  5. POJ 2104 求序列里第K大 主席树裸题

    给定一个n的序列,有m个询问 每次询问求l-r 里面第k大的数字是什么 只有询问,没有修改 可以用归并树和划分树(我都没学过..囧) 我是专门冲着弄主席树来的 对主席树的建树方式有点了解了,不过这题为 ...

  6. 【BZOJ 1901】【Zju 2112】 Dynamic Rankings 动态K值 树状数组套主席树模板题

    达神题解传送门:http://blog.csdn.net/dad3zz/article/details/50638360 说一下我对这个模板的理解: 看到这个方法很容易不知所措,因为动态K值需要套树状 ...

  7. 主席树:POJ2104 K-th Number (主席树模板题)

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 44952   Accepted: 14951 Ca ...

  8. SPOJ MKTHNUM & POJ 2104 - K-th Number - [主席树模板题]

    题目链接:http://poj.org/problem?id=2104 Description You are working for Macrohard company in data struct ...

  9. POJ 2104 K-th Number(主席树模板题)

    http://poj.org/problem?id=2104 题意:求区间$[l,r]$的第k小. 思路:主席树不好理解啊,简单叙述一下吧. 主席树就是由多棵线段树组成的,对于数组$a[1,2...n ...

随机推荐

  1. [Angular 2] Dispatching Action with Payloads and type to Reducers

    While action types allow you tell your reducer what action it should take, the payload is the data t ...

  2. [React] Radium: Updating Button Styles via Props

    In a CSS library like Bootstrap we can set a button's style to be "primary" or "secon ...

  3. [Unit Testing] Angular Unit Testing, ui-router, httpbackend and spy

    // backend test beforeEach(inject(function (_$compile_, _$httpBackend_, _$rootScope_, _$state_, _Ann ...

  4. oracle中split的使用

    1.创建自己的类型 VARCHAR2ARRAY CREATE OR REPLACE TYPE "VARCHAR2ARRAY" as table of varchar2(300); ...

  5. 头像上传ASP.NET MVC实现-可拖动大小实时预览

    这是一个ASP.NET MVC实现的类似于dz论坛的上传头像功能.可以拖动选择大小,支持多种尺寸生成. 效果界面 头像上传源码下载 项目中具体应用时,请根据需求做调整.欢迎交流~回复即可下载~源码下载 ...

  6. NYOJ -37回文字符串

    这道题看了好大会没有思路,上网一搜发现这么简单,但是我为什么就想不到呢,??就是求和它的逆序之后的字符串最长公共子序列,然后用总的长度减去它就行了.原因是是因为只要是在公共子序列里面,那么他就是对称的 ...

  7. JavaScript基础(二)

    一.外部引用语法<script src="script.js"></script> 二.在页面中的位置 1.我们可以将JavaScript代码放在html文 ...

  8. activiti总结

    1.activiti如何修改登录用户名?在哪个数据库里面添加. 2.activiti的启动和部署在http://activiti.org/userguide/index.html#demo.setup ...

  9. zookeeper主要使用场景

    场景一:有一组服务器向客户端提供某种服务,我们希望客户端每次请求服务端都可以找到服务端集群中某一台服务器,这样服务端就可以向客户端提供客户端所需的服务.对于这种场景,我们的程序中一定有一份这组服务器的 ...

  10. MD5加密运算

    //MD5 对字符串的加密 -(void)demo1 { NSString *str = @"love"; //对字符串进行MD5加密 str = str.md5String; N ...