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

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. ural1519-Formula 1

    题意 给出一个 \(n\times m\) 的棋盘,上面有一些格子是不能经过的.求有多少种欧拉回路可以经过所有可经过到格子.\(n,m\le 12\) . 分析 上个月就看了一下插头dp,然而这道题写 ...

  2. OpenGL 加载DDS文件(压缩纹理)

    想必很多人都见过DDS这种文件,它是一个“图片文件”,如果你安装了某些看图软件,你可以直接双击打开它来进行预览. 那么,这种DDS文件和我们常见的TGA/PNG之类的文件有何不同呢? DDS和TGA/ ...

  3. redis的数据持久化存储

    Redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到硬盘来保证持久化.Redis支持两种持久化方式: 一.snapshotting(快照)方式快照是默认的持久化方式. ...

  4. [学习笔记]搜索——模拟与dp的结合

    搜索: 一种基础的算法. 考察常见于NOIP 但是高级的搜索算法可能还会在省选出现. 50%以上的暴力都可以用搜索直接枚举来写. 但是,当数据规模不是很大的时候,搜索也可能成为正解. (比如剪枝PK状 ...

  5. git使用笔记(十三)ls-files

    By francis_hao    Mar 18,2018   git ls-fles 显示index和工作区的文件的信息. 概要 git ls-files [-z] [-t] [-v]        ...

  6. 根据数据库连接的java.sql.Connection获取数据库名称

    // 获取数据库的元数据信息 DatabaseMetaData metaData = conn.getMetaData(); // 获取数据库名称的方法 System.out.println(meta ...

  7. bzoj1467 Pku3243 clever Y

    1467: Pku3243 clever Y Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 313  Solved: 181[Submit][Status ...

  8. Ubuntu配置vncserver

    https://help.aliyun.com/knowledge_detail/59330.html 首先,安装桌面环境和vnc4server: sudo apt-get install gnome ...

  9. mysql日志配置

    mysql在错误排查,优化的时候会用到日志 有错误日志,查询日志,慢查询日志,二进制日志 先找到日志文件,linux 一般在/etc/my.cnf中 打开看到 log-error=/webserver ...

  10. select网络模型知识总结

    select模型支持IO多路复用,select函数如下 int select ( IN int nfds, //windows下无意义,linux有意义 IN OUT fd_set* readfds, ...