版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu 4605

题意:

  有一颗树,根节点为1,每一个节点要么有两个子节点,要么没有,每个节点都有一个权值wi 。然后,有一个球,附带值x 。

  球到达某个节点上,如果x==wi,那么球停在这个节点上 。当然,这个点是叶子节点也会停止 。

  如果x<wi,那么有1/2的概率走向左子树,有1/2的概率走向右子树 。

  如果x>wi,那么有1/8的概率走向左子树,有7/8的概率走向右子树 。

  问球经过v节点的概率 。(停在v节点也算)

解法:

  在线的话每一个节点建一棵根节点到该节点的线段树,离线的话就先把询问按DFS序排序,然后瞎搞搞就ok了 。。。

在线主席树

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#define ll long long using namespace std; const int N=; int Ls[N*],Rs[N*],cnt[N*][];
int root[N],tot; int e[N][];
int w[N],sort_w[N]; int n; inline int Hash(int x){
return upper_bound(sort_w+,sort_w+n+,x)-sort_w-;
} inline void init(){
tot=;
memset(e,-,sizeof(e));
} inline int bulidtree(int L,int R){
int k=tot++;
cnt[k][]=cnt[k][]=;
if (L==R) return k;
int mid=(L+R)>>;
Ls[k]=bulidtree(L,mid);
Rs[k]=bulidtree(mid+,R);
return k;
} inline void copy(int x,int y){
Ls[x]=Ls[y];
Rs[x]=Rs[y];
cnt[x][]=cnt[y][];
cnt[x][]=cnt[y][];
} // to 0 左子树 1 右子树
inline int update(int o,int p,int to,int L,int R){
int k=tot++;
copy(k,o);
cnt[k][to]++;
if (L==R) return k;
int mid=(L+R)>>;
if (p<=mid) Ls[k]=update(Ls[k],p,to,L,mid);
else Rs[k]=update(Rs[k],p,to,mid+,R);
return k;
} inline int query(int o,int x,int y,int to,int L,int R){
if (x>y) return ;
if (L==x && R==y) return cnt[o][to];
int mid=(L+R)>>;
if (y<=mid) return query(Ls[o],x,y,to,L,mid);
else if (x>mid) return query(Rs[o],x,y,to,mid+,R);
else return query(Ls[o],x,mid,to,L,mid)+query(Rs[o],mid+,y,to,mid+,R);
} inline void dfs(int u){
for (int i=;i<=;i++) if (~e[u][i]) {
int v=e[u][i];
root[v]=update(root[u],Hash(w[u]),i,,n);
dfs(v);
}
} int main(){
int t,m,q;
scanf("%d",&t);
while (t--){
init(); scanf("%d",&n);
for (int i=;i<=n;i++) {
scanf("%d",&w[i]);
sort_w[i]=w[i];
}
sort(sort_w+,sort_w+n+); scanf("%d",&m);
while (m--){
int u,a,b;
scanf("%d %d %d",&u, &a, &b);
e[u][]=a;
e[u][]=b;
} root[]=bulidtree(,n); dfs(); scanf("%d",&q);
while (q--){
int v,x;
scanf("%d %d",&v,&x);
int id=Hash(x);
if (x==sort_w[id]){
if (query(root[v],id,id,,,n) || query(root[v],id,id,,,n)){
puts("");
continue;
}
} int L_down=query(root[v],,id,,,n);
int L_up=query(root[v],id+,n,,,n);
int R_down=query(root[v],,id,,,n);
int R_up=query(root[v],id+,n,,,n); printf("%d %d\n",R_down,L_up+R_up+*L_down+*R_down);
}
} return ;
}

离线树状数组

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#define ll long long using namespace std; const int N=; int w[N],e[N][];
int sort_w[N];
int c[N][]; // 树状数组
int n,Q;
int pos[N];
int ans[N][]; struct QUERY{
int v,x,id;
int s;
bool operator < (const QUERY & t) const {
return s<t.s;
}
}q[N]; inline int Hash(int x){
return upper_bound(sort_w+,sort_w+n+,x)-sort_w-;
} inline void init(){
memset(c,,sizeof(c));
memset(e,,sizeof(e));
} inline int lowbit(int x){
return x&(-x);
} inline void add(int x,int d,int to){
while (x<=n){
c[x][to]+=d;
x+=lowbit(x);
}
} inline int sum(int x,int to){
int ret=;
while (x){
ret+=c[x][to];
x-=lowbit(x);
}
return ret;
} inline int query(int L,int R,int to){
return sum(R,to)-sum(L-,to);
} int cnt;
inline void dfs1(int u){
pos[u]=++cnt;
for (int i=;i<=;i++) if (e[u][i])
dfs1(e[u][i]);
} inline void dfs2(int u){
while (cnt<=Q && q[cnt].v==u){
int id=Hash(q[cnt].x);
if (sort_w[id]==q[cnt].x){
if (query(id,id,) || query(id,id,)){
ans[q[cnt].id][]=-;
cnt++;
continue;
}
} int L_down=query(,id,);
int L_up=query(id+,n,);
int R_down=query(,id,);
int R_up=query(id+,n,); ans[q[cnt].id][]=R_down;
ans[q[cnt].id][]=L_up+R_up+*L_down+*R_down;
cnt++;
} int id=Hash(w[u]);
for (int i=;i<=;i++) if (e[u][i]) {
add(id,,i);
dfs2(e[u][i]);
add(id,-,i);
}
} int main(){
int t,m;
scanf("%d",&t);
while (t--){
init(); scanf("%d",&n);
for (int i=;i<=n;i++) {
scanf("%d",&w[i]);
sort_w[i]=w[i];
}
sort(sort_w+,sort_w+n+); scanf("%d",&m);
for (int i=;i<=m;i++){
int u,a,b;
scanf("%d %d %d",&u, &a, &b);
e[u][]=a;
e[u][]=b;
} scanf("%d",&Q);
for (int i=;i<=Q;i++){
scanf("%d%d",&q[i].v,&q[i].x);
q[i].id=i;
} cnt=;
dfs1(); for (int i=;i<=Q;i++) q[i].s=pos[q[i].v];
sort(q+,q+Q+); cnt=;
dfs2(); for (int i=;i<=Q;i++){
if (~ans[i][]) printf("%d %d\n",ans[i][],ans[i][]);
else puts("");
}
} return ;
}

hdu 4605 Magic Ball Game (在线主席树/离线树状数组)的更多相关文章

  1. HDU 4605 Magic Ball Game (在线主席树|| 离线 线段树)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意:给出一棵二叉树,每个结点孩子数目为0或者2. ...

  2. HDU 4605 Magic Ball Game(可持续化线段树,树状数组,离散化)

    Magic Ball Game Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  3. HDU 4605 Magic Ball Game (dfs+离线树状数组)

    题意:给你一颗有根树,它的孩子要么只有两个,要么没有,且每个点都有一个权值w. 接着给你一个权值为x的球,它从更节点开始向下掉,有三种情况 x=w[now]:停在此点 x<w[now]:当有孩子 ...

  4. HDU 4605 Magic Ball Game 树状数组

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

  5. hdu 4605 Magic Ball Game

    http://acm.hdu.edu.cn/showproblem.php?pid=4605 可以离线求解 把所以可能出现的 magic ball  放在一个数组里(去重),从小到大排列 先不考虑特殊 ...

  6. HDU 4605 Magic Ball Game 主席树

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

  7. HDU 4605 Magic Ball Game(离线算法)

    题目链接 思路就很难想+代码实现也很麻烦,知道算法后,已经写的很繁琐而且花了很长时间,200+,好久没写过这么长的代码了. #pragma comment(linker, "/STACK:1 ...

  8. HDU 4602 Magic Ball Game(离线处理,树状数组,dfs)

    Magic Ball Game Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  9. 【HDOJ】4605 Magic Ball Game

    思路1:树状数组+离线处理,对所有的w离散化处理,边dfs边使用树状数组更新左右w的情况.思路2:主席树,边bfs边建树.结点信息存储cnt,然后在线查询.树状数组. /* 4605 */ #incl ...

随机推荐

  1. 学习Python最好的方法就是实践和教程并行,以下有一些资源和教程,还有一些学习思维导图:

    1.Python 的 14 张思维导图下载地址: https://woaielf.github.io/2017/06/13/python3-all/ 2.Python基础教程|菜鸟教程: http:/ ...

  2. Oracle 同名字段的该行数据按照创建时间最新的隐藏其他

    1.需求,表  SYS_INFO   的 NAME 字段会重复,按照  创建时间CREATE_AT 字段,取最新一条,其他隐藏 SELECT * FROM (SELECT T.*,ROW_NUMBER ...

  3. 温习classList api

    有道题是一个removeClass的功能,代码里是正则分隔了传入的name,根据name的个数,循环移除掉,让寻找bug..看了了这几行代码,首先想到的是我会如何去优化. 如果看代码一两分钟就能找到公 ...

  4. 2017 Multi-University Training Contest - 2

    HDU 6045 #pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #in ...

  5. 我的emacs简易配置

    ;;------------语言环境字符集设置(utf-8)------------- (set-language-environment 'Chinese-GB) (set-keyboard-cod ...

  6. sloop公共程序之初始过程及启动

    1:sloop_init() 初始化主要是初始化静态sloop_*** 结构体和填充struct sloop_data 结构体中的成员. //初始化静态存储区给sloop_***结构体 static ...

  7. 层级 z-index 透明opacity

    在正常情况下,层级的大小由顺序决定,后面的元素要比前面的元素的层级要高 有定位元素的层级要比没有定位元素层级要高 在都有定位的情况下,层级还是取决于书写顺序 z-index 层级(仅能在定位元素上奏效 ...

  8. 前端PHP入门-024-字符串函数-API查看

    数组.字符串和数据库是我们函数里面最.最.最常用的三类函数,数组和数据库我们现在还没有讲到,等讲到的时候我们再来和大家细说. 当然PHP的字符串函数也有很多.我们最常使用的两个系列的字符串: 单字节字 ...

  9. 2017-2018-2 20179207 《网络攻防技术》第十三周作业 python3实现SM234算法

    国密算法SM234 的python3实现 国家标准 GM/T 0002-2012 <SM4分组密码算法> GM/T 0003.1-2012 <SM2椭圆曲线公钥密码算法 第1部分:总 ...

  10. 分块+lazy 或者 线段树+lazy Codeforces Round #254 (Div. 2) E

    E. DZY Loves Colors time limit per test 2 seconds memory limit per test 256 megabytes input standard ...