http://acm.hdu.edu.cn/showproblem.php?pid=4605

可以离线求解

把所以可能出现的 magic ball  放在一个数组里(去重),从小到大排列

先不考虑特殊情况,对二叉树进行dfs 搜索的过程中需要维护各个magic ball到当前节点的概率

维护:根据当前节点大小 和要去左子树还是右子树的情况,可以得到magic数组中哪个段的x和y需要同时加上多少

可以用线段树维护

特殊情况:

1,根节点一定可以到达

2,到达不了的情况需要标记

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
#include<queue>
#include<stdexcept>
#include<bitset>
#include<cassert>
#include<deque>
#include<numeric> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; typedef long long ll;
typedef unsigned int uint;
typedef pair<int,int> pp;
const double eps=1e-12;
const int INF=0x3f3f3f3f;
const ll MOD=1000000007;
const int N=100010;
struct node
{
int l,r;
int fm,fn;
}tree[N*4];
int f[N];
int a[N];
int stop[N];
int qv[N],qx[N],qm[N],qn[N];
int bl[N],br[N];
int weight[N];
vector<int>vt[N];
void build(int x,int l,int r)
{
tree[x].l=l;
tree[x].r=r;
tree[x].fm=0;
tree[x].fn=0;
if(l==r)
return ;
int mid=(l+r)>>1;
build((x<<1),l,mid);
build((x<<1)|1,mid+1,r);
}
void add(int x,int l,int r,int km,int kn)
{
if(l>r) return ;
if(tree[x].l==l&&tree[x].r==r)
{
tree[x].fm+=km;
tree[x].fn+=kn;
return ;
}
int mid=(tree[x].l+tree[x].r)>>1;
if(r<=mid)
add((x<<1),l,r,km,kn);
else if(l>mid)
add((x<<1)|1,l,r,km,kn);
else
{
add((x<<1),l,mid,km,kn);
add((x<<1)|1,mid+1,r,km,kn);
}
}
void get(int x,int k,int &m,int &n)
{
m+=tree[x].fm;n+=tree[x].fn;
if(tree[x].l==tree[x].r)
{return ;}
int mid=(tree[x].l+tree[x].r)>>1;
if(k<=mid)
get((x<<1),k,m,n);
else
get((x<<1)|1,k,m,n);
}
int bse(int l,int r,int k)
{
while(l<=r)
{
int m=(l+r)>>1;
if(a[m]<=k)
l=m+1;
else
r=m-1;
}
return r;
}
void dfs(int x,int ln)
{
for(unsigned int i=0;i<vt[x].size();++i)
{
int t=vt[x][i];
int w=bse(1,ln,qx[t]);
int m=0,n=0;
if(!stop[w])
{get(1,w,m,n);}
qm[t]=m;
qn[t]=n;
}
if(bl[x]!=0&&br[x]!=0)
{
int l=bse(1,ln,weight[x]);
int ll=l,rr=l+1;
if(a[l]==weight[x])
stop[l]++;
add(1,1,ll,0,1);
add(1,rr,ln,0,3);
dfs(bl[x],ln);
add(1,1,ll,0,-1);
add(1,rr,ln,0,-3); add(1,1,ll,0,1);
add(1,rr,ln,1,3);
dfs(br[x],ln);
add(1,1,ll,0,-1);
add(1,rr,ln,-1,-3);
if(a[l]==weight[x])
stop[l]--;
}
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("1006.in","r",stdin);
//freopen("my.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
for(int i=0;i<N;++i)
vt[i].clear();
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",&weight[i]);
int m;
scanf("%d",&m);
memset(bl,0,sizeof(bl));
memset(br,0,sizeof(br));
while(m--)
{
int v,l,r;
scanf("%d %d %d",&v,&l,&r);
f[l]=v;
f[r]=v;
bl[v]=l;
br[v]=r;
}
int ln=0;
a[++ln]=0;
a[++ln]=1e9+10;
int Q;
scanf("%d",&Q);
for(int i=0;i<Q;++i)
{
scanf("%d %d",&qv[i],&qx[i]);
a[++ln]=qx[i];
if(qv[i]!=1)
{
vt[qv[i]].push_back(i);
}
}
sort(a+1,a+ln+1);
int l=0;
for(int i=1;i<=ln;++i)
if(i==1||a[i]!=a[i-1])
a[++l]=a[i];
ln=l; build(1,1,ln);
memset(stop,0,sizeof(stop));
dfs(1,ln); for(int i=0;i<Q;++i)
{
if(qv[i]==1)
{printf("0 0\n");continue;} if(qm[i]==0&&qn[i]==0)
printf("0\n");
else
printf("%d %d\n",qm[i],qn[i]);
}
}
return 0;
}

hdu 4605 Magic Ball Game的更多相关文章

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

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

  2. hdu 4605 Magic Ball Game (在线主席树/离线树状数组)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4605 题意: 有一颗树,根节点为1,每一个节点要么有两个子节点,要么没有,每个节点都有一个权值wi .然后,有一个球,附带值x . 球 ...

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

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

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

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

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

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

  6. HDU 4605 Magic Ball Game 树状数组

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

  7. HDU 4605 Magic Ball Game 主席树

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

  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学习(9)列表

    目录 Python 列表 访问列表中的值 更新列表 删除列表元素 列表脚本操作符 列表截取 列表函数&方法 Python 列表(List) 序列是Python中最基本的数据结构.序列中的每个元 ...

  2. (转)接口自动化测试 – Java+TestNG 测试 Restful Web Service

    本文主要介绍如何用Java针对Restful web service 做接口自动化测试(数据驱动),相比UI自动化,接口自动化稳定性可靠性高,实施难易程度低,做自动化性价比高.所用到的工具或类库有 T ...

  3. Win7_64位使用Mysql Odbc

    1.首先不能安装Mysql Odbc 64位,因为我们的Mysql是32位,使用Mysql Odbc 64位连接Mysql 32位,报错:驱动程序与应用程序之间的体系结构不匹配. 2.要安装Mysql ...

  4. IIS Express简介

    当前程序员只能通过下面两种Web服务器之一来开发和测试ASP.NET网站程序: 1. Visual Studio自带的ASP.NET开发服务器(webdev.exe). 2. Windows自带的II ...

  5. Jump Game II

    Description: Given an array of non-negative integers, you are initially positioned at the first inde ...

  6. Android menu 简单创建

    在android 中与menu相关的类有4个: Menu:菜单的父窗口,用于创建一个菜单,是subMenu,ContentMenu,MenuItem等的父接口:SubMenuyo用于创建子菜单,Con ...

  7. hiho1122_二分图匈牙利算法

    题目 给定一个图的N个节点和节点之间的M条边,数据保证该图可以构成一个二分图.求该二分图最大匹配. 题目链接:二分图最大匹配     首先通过染色法,将图的N个节点分成两个部分:然后通过匈牙利算法求二 ...

  8. php 新特性

    PHP 5.6 1.可以使用表达式定义常量 https://php.net/manual/zh/migration56.new-features.php 在之前的 PHP 版本中,必须使用静态值来定义 ...

  9. wampserver2.5 apache2.4.9:forbidden,本机可以访问,局域网内部能访问。

    wampserver2.5 apache2.4.9:forbidden,本机可以访问,局域网内部能访问. 因为做项目,多人分工,需要局域网内访问各自的项目. 然后安装了wampserver2.5,Ap ...

  10. Jenkins运行完Test后,把ngreport生成的测试报告 拷贝到相应的文件夹

    F:cd F:\program\apache-tomcat-7.0.67\webapps\Set currentPath=F:\program\apache-tomcat-7.0.67\webapps ...