hdu4605
两颗线段树,分别维护向左走向右走的情况
线段树的结点维护区间有多少点被路径经过了
离线读入所有询问,dfs遍历树的每一个结点,访问到v时解决对v的所有查询,在dfs过程中只需要维护根节点到v的链,线段树查询链上有多少结点值大于或小于询问的x,即能求出到达x的概率
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<string.h>
/*
类似二叉搜索树
给定一颗n个结点的二叉树
给定数值x,从root开始沿着二叉树往下搜索,分三种情况
1.搜到叶子结点或者结点权值等于X,停止搜索
2.搜到结点权值w<x,搜索左右儿子几率各为1/2
3.w>=x,搜索左右儿子几率各为1/8,7/8
问v点被搜索到的概率是多少 两棵线段树保存向左走向右走的结果分布情况
离线+dfs
*/
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
#define maxn 110000
#define lmin 1
#define rmax len
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define root lmin,rmax,1
#define now l,r,rt
#define int_now int l,int r,int rt
#define INF 999999999999
#define LL long long
#define mod 10007
struct list
{
int father;
int l,r;
int w;
}node[maxn];//树的结点
vector<int>vec[maxn];//询问结点v的问题编号
struct listt
{
int x,y;
int v;
int w;
}qq[maxn];//询问
map<int,int>mp;
int len;
int fs[maxn*];//离散化后的权值
int st=;
int sum[maxn*][];//两棵线段树
void updata(int ll,int rr,int x,int leap,int_now)
{
if(ll>r||rr<l)return;
if(ll<=l&&rr>=r)
{
sum[rt][leap]+=x;
return;
}
updata(ll,rr,x,leap,lson);
updata(ll,rr,x,leap,rson);
sum[rt][leap]=sum[rt<<][leap]+sum[rt<<|][leap];
}
int query(int ll,int rr,int leap,int_now)
{
if(ll>r||rr<l)return ;
if(ll<=l&&rr>=r)return sum[rt][leap];
return query(ll,rr,leap,lson)+query(ll,rr,leap,rson);
}
void dfs(int x)
{
for(int i=;i<vec[x].size();i++)//遍历结点x对应的每个询问
{
int bi=vec[x][i];
int w=qq[bi].w;
w=mp[w];
int nm=query(w,w,,root)+query(w,w,,root);//nm只有在走不到x结点时才非0
int ll=query(,w-,,root);//root到x路径上结点权值小于w并且球向左走的点个数
int lr=query(w+,len,,root);//root到x路径上结点权值大于w并且球向左走的点个数
int rl=query(,w-,,root);//root到x路径上结点权值小于w并且球向左走的点个数
int rr=query(w+,len,,root);//root到x路径上结点权值小于w并且球向左走的点个数;
if(nm!=)continue;
qq[bi].x=rl;
qq[bi].y=(ll+rl)*+lr+rr; }
int id=mp[node[x].w];
if(node[x].l!=)
{
updata(id,id,,,root);//在向左走的线段树中更新当前结点的权值
dfs(node[x].l);
updata(id,id,-,,root);//回溯,取消本次更新
}
if(node[x].r!=)
{
updata(id,id,,,root);
dfs(node[x].r);
updata(id,id,-,,root);
}
}
int main()
{
int T,n,m,u,l,r;
scanf("%d",&T);
while(T--)
{
st=;
memset(sum,,sizeof(sum));
memset(node,,sizeof(node));
mp.clear();
scanf("%d",&n);
len=;
for(int i=;i<=n;i++)
{
scanf("%d",&node[i].w);
fs[++st]=node[i].w;
vec[i].clear();
}
scanf("%d",&m);
while(m--)
{
scanf("%d%d%d",&u,&l,&r);
node[l].father=node[r].father=u;
node[u].l=l;
node[u].r=r;
}
node[].father=-;
int q,v,ww;
scanf("%d",&q);
for(int i=;i<=q;i++)
{
scanf("%d%d",&v,&ww);
fs[++st]=ww;
qq[i].v=v;
qq[i].w=ww;
qq[i].x=qq[i].y=-;
vec[v].push_back(i);
}
sort(fs+,fs+st+);
len=;
fs[]=-;
for(int i=;i<=st;i++)
{
if(fs[i]!=fs[i-])
{
if(mp.find(fs[i])==mp.end())
{
mp[fs[i]]=++len;
}
}
}
dfs();
for(int i=;i<=q;i++)
{
if(qq[i].x==-)puts("");
else
{
printf("%d %d\n",qq[i].x,qq[i].y);
}
}
}
return ;
}
hdu4605的更多相关文章
- hdu4605 树状数组+离散化+dfs
Magic Ball Game Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- hdu4605 magic ball game 树状数组+离线处理
题意:给你一棵二叉树,每个节点有一个w值,现在有一颗小球,值为x,从根节点往下掉,如果w==x,那么它就会停止:如果w>x,那么它往左.右儿子的概率都是1.2:如果w<x,那么它往左儿子的 ...
- HDU-4605 Magic Ball Game 树状数组+离散+dfs
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4605 题意:给一颗树,每个节点有个权值w[u],每个节点只有两个儿子或者没有儿子,从根节点放下一个小球 ...
- 2013 Multi-University Training Contest 1
HDU-4605 Magic Ball Game 题意:给定一颗以1为根的数,每个节点要么有两个孩子节点,要么没有孩子,每个节点有一个重量,现在从节点1往下放置一个小球,根据小球和节点的重量的不同球落 ...
- HDU5140---Hun Gui Wei Company (主席树)
主席树太强大了,,如果仅仅用来求第k大就太屈才了..貌似和HDU4605差不多,那个是在图上根据点的顺序建立主席树,这个是根据年龄大小 或者等级高低建立主席树. 题意 大致就是一个二维区间的求和,但是 ...
随机推荐
- Java ExecutorService四种线程池的例子与说明
1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? new Thread(new Runnable() { @Override public void run() { ...
- js event 冒泡和捕获事件详细介绍【转】
冒泡和捕获 冒泡: 事件从内向外,从下向上执行 (默认行为) 捕获: 事件从外向内,从上向下执行 vue之capture 捕获事件 capture.html <!DOCTYPE html> ...
- SGU 271 Book Pile
There is a pile of N books on the table. Two types of operations are performed over this pile: - a b ...
- 求幂运算、多项式乘法及Horner法则的应用
一,两种不同的求幂运算 求解x^n(x 的 n 次方) ①使用递归,代码如下: private static long pow(int x, int n){ if(n == 0) return 1; ...
- Spring MVC 源码分析
Spring MVC SpringMVC中扮演关键角色的DispatcherServlet类. 1 DispatcherServlet 1.1DispatcherServlet 类图 1.2 初始 ...
- Anaconda的安装和更新
下载地址官网:https://www.anaconda.com/distribution/ 一.安装 二.下载安装完成后我们来检验一下是否安装成功 点击“开始” —— “Anaconda3(64-bi ...
- [C++]数组与指针[二维数组与指针]
- OO第三阶段总结
软件形式化方法历史 形式化方法的研究高潮始于20世纪60年代后期,针对当时所谓"软件危机",人们提出种种解决方法,归纳起来有两类:一是采用工程方法来组织.管理软件的开发过程:二是深 ...
- 【转贴】Linux下MySQL 5.5的修改字符集编码为UTF8(彻底解决中文乱码问题)
原文地址; http://www.ha97.com/5359.html PS:昨天一同事遇到mysql 5.5中文乱码问题,找我解决.解决了,有个细节问题网上没人说,我就总结一下. 一.登录MySQL ...
- python正则表达式二[转]
原文:http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html 1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一 ...