两颗线段树,分别维护向左走向右走的情况

线段树的结点维护区间有多少点被路径经过了

离线读入所有询问,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的更多相关文章

  1. hdu4605 树状数组+离散化+dfs

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

  2. hdu4605 magic ball game 树状数组+离线处理

    题意:给你一棵二叉树,每个节点有一个w值,现在有一颗小球,值为x,从根节点往下掉,如果w==x,那么它就会停止:如果w>x,那么它往左.右儿子的概率都是1.2:如果w<x,那么它往左儿子的 ...

  3. HDU-4605 Magic Ball Game 树状数组+离散+dfs

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4605 题意:给一颗树,每个节点有个权值w[u],每个节点只有两个儿子或者没有儿子,从根节点放下一个小球 ...

  4. 2013 Multi-University Training Contest 1

    HDU-4605 Magic Ball Game 题意:给定一颗以1为根的数,每个节点要么有两个孩子节点,要么没有孩子,每个节点有一个重量,现在从节点1往下放置一个小球,根据小球和节点的重量的不同球落 ...

  5. HDU5140---Hun Gui Wei Company (主席树)

    主席树太强大了,,如果仅仅用来求第k大就太屈才了..貌似和HDU4605差不多,那个是在图上根据点的顺序建立主席树,这个是根据年龄大小 或者等级高低建立主席树. 题意 大致就是一个二维区间的求和,但是 ...

随机推荐

  1. vue2.0 之表单控件绑定

    表单控件绑定v-model 1.文本 <template> <div> <input type="text" name="" v- ...

  2. grafana-zabbix部署和使用

    grafana-zabbix安装 官网安装介绍地址:https://grafana.com/plugins/alexanderzobnin-zabbix-app/installation 下载地址:h ...

  3. 函数和常用模块【day04】:内置函数(九)

    一.11-20 11.ord(c) 功能:根据字符,找到对应的ascii值 1 2 >>> ord('a') 97 12.classmethod(function) 功能:类方法,这 ...

  4. css before after基本用法【转】

    <HTML><HEAD> <meta http-equiv="content-Type"content="text/html;charset ...

  5. POJ - 1584 A Round Peg in a Ground Hole(判断凸多边形,点到线段距离,点在多边形内)

    http://poj.org/problem?id=1584 题意 按照顺时针或逆时针方向输入一个n边形的顶点坐标集,先判断这个n边形是否为凸包. 再给定一个圆形(圆心坐标和半径),判断这个圆是否完全 ...

  6. scipy笔记—scipy.misc.imresize用法(方便训练图像数据)

    scipy.misc.imresize 不同于普通的reshape, imresize不是单纯的改变图像矩阵的维度,而是能将图片重采样为指定像素,这样给深度学习中训练图像数据带来方便. import ...

  7. Linux 命令详解(十)Shell脚本的数组详解

    1.数组定义 [root@bastion-IDC ~]# a=( ) [root@bastion-IDC ~]# echo $a 一对括号表示是数组,数组元素用“空格”符号分割开. 2.数组读取与赋值 ...

  8. 转--python 面试题

    # 每一题都值得好好琢磨钻透 [原文地址](http://www.cnblogs.com/Allen-rg/p/7693394.html)1.Python是如何进行内存管理的? 答:从三个方面来说,一 ...

  9. NPOI 2.3

    样例 //设置员工编号单元格为文本格式 循环效率问题? IDataFormat dataformat = workbook.CreateDataFormat(); ICellStyle style1 ...

  10. JavaScript之不规则Table转化为可定点索引td节点的网格矩阵【插件】

    由于解析课程表的缘故,有如下需求: 1. 将任意表格解析成独立的单元格矩阵[本次博文的缘由] 2. 根据矩阵坐标,确定任意一格的节点   /* 表格-->网格化 标记表格的位置及其对应的节点 * ...