$dfs$序,线段树。

可以统计每一个节点作为$root$的子树上对答案的贡献,可以将树转换成序列。问题就变成了一段区间上求小于等于某个值的数有几个。用线段树记录排好序之后的区间序列,询问的时候,属于询问区间的每个节点二分一下统计答案即可。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
char c=getchar(); x=;
while(!isdigit(c)) c=getchar();
while(isdigit(c)) {x=x*+c-''; c=getchar();}
} const int maxn=;
int T,n,h[maxn],sz,r[maxn],root;
LL k,v[maxn];
struct Edge { int u,v,nx; }e[maxn];
LL a[*maxn],L[*maxn],R[*maxn];
vector<int>s[*maxn]; void add(int u,int v)
{
e[sz].u=u; e[sz].v=v;
e[sz].nx=h[u]; h[u]=sz++;
} void dfs(int x)
{
sz++; a[sz]=v[x]; L[x]=sz;
for(int i=h[x];i!=-;i=e[i].nx) dfs(e[i].v);
sz++; a[sz]=v[x]; R[x]=sz;
} void build(int l,int r,int rt)
{
if(l==r) { s[rt].push_back(a[l]); return; }
int m=(l+r)/; build(l,m,*rt); build(m+,r,*rt+); int sum=,p1=,p2=;
while(sum<r-l+)
{
if(p1<s[*rt].size()&&p2<s[*rt+].size())
{
if(s[*rt][p1]<s[*rt+][p2]) s[rt].push_back(s[*rt][p1]), p1++;
else s[rt].push_back(s[*rt+][p2]), p2++;
}
else if(p1<s[*rt].size()) s[rt].push_back(s[*rt][p1]), p1++;
else s[rt].push_back(s[*rt+][p2]), p2++;
sum++;
}
} int get(int L,int R,LL num,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
int left=,right=r-l,pos=-; while(left<=right)
{
int mid=(left+right)/;
if((LL)s[rt][mid]>num) right=mid-;
else left=mid+,pos=mid;
} return pos+;
} int m=(l+r)/,x1=,x2=;
if(L<=m) x1=get(L,R,num,l,m,*rt);
if(R>m) x2=get(L,R,num,m+,r,*rt+);
return x1+x2;
} int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%lld",&n,&k);
for(int i=;i<=n;i++) scanf("%lld",&v[i]); memset(h,-,sizeof h);
memset(r,sz=,sizeof r);
for(int i=;i<*maxn;i++) s[i].clear(); for(int i=;i<=n-;i++)
{
int u,v; scanf("%d%d",&u,&v);
add(u,v); r[v]++;
} for(int i=;i<=n;i++) if(r[i]==) root=i;
sz=; dfs(root); build(,*n,); LL Ans=;
for(int i=;i<=n;i++)
{
if(L[i]+==R[i]) continue;
if(v[i]==) { Ans=Ans+(R[i]-L[i]-); continue; }
Ans=Ans+get(L[i]+,R[i]-,k/v[i],,*n,);
}
printf("%lld\n",Ans/);
}
return ;
}

HDU 5877 Weak Pair的更多相关文章

  1. HDU 5877 Weak Pair(弱点对)

    HDU 5877 Weak Pair(弱点对) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Jav ...

  2. 树形DP+树状数组 HDU 5877 Weak Pair

    //树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...

  3. hdu 5877 Weak Pair (Treap)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5877 题面; Weak Pair Time Limit: 4000/2000 MS (Java/Other ...

  4. 2016 ACM/ICPC Asia Regional Dalian Online HDU 5877 Weak Pair treap + dfs序

    Weak Pair Problem Description   You are given a rooted tree of N nodes, labeled from 1 to N. To the  ...

  5. HDU - 5877 Weak Pair (dfs+树状数组)

    题目链接:Weak Pair 题意: 给出一颗有根树,如果有一对u,v,如果满足u是v的父节点且vec[u]×vec[v]<=k,则称这对结点是虚弱的,问这棵树中有几对虚弱的结点. 题解: 刚开 ...

  6. HDU 5877 Weak Pair (2016年大连网络赛 J dfs+反向思维)

    正难则反的思想还是不能灵活应用啊 题意:给你n个点,每个点有一个权值,接着是n-1有向条边形成一颗有根树,问你有多少对点的权值乘积小于等于给定的值k,其中这对点必须是孩子节点与祖先的关系 我们反向思考 ...

  7. hdu 5877 Weak Pair dfs序+树状数组+离散化

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Prob ...

  8. HDU 5877 Weak Pair(树状数组)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5877 [题目大意] 给出一棵带权有根树,询问有几对存在祖先关系的点对满足权值相乘小于等于k. [题 ...

  9. HDU 5877 Weak Pair(树状数组+dfs+离散化)

    http://acm.hdu.edu.cn/showproblem.php?pid=5877 题意: 给出一棵树,每个顶点都有权值,现在要你找出满足要求的点对(u,v)数,u是v的祖先并且a[u]*a ...

  10. HDU 5877 Weak Pair DFS + 树状数组 + 其实不用离散化

    http://acm.hdu.edu.cn/listproblem.php?vol=49 给定一颗树,然后对于每一个节点,找到它的任何一个祖先u,如果num[u] * num[v] <= k.则 ...

随机推荐

  1. 2013.5.A

    题1 高低位交换 [问题描述] 给出一个小于2^32的正整数.这个数可以用一个32位的二进制数表示(不足32位用0补足).我们称这个二进制数的前16位为“高位”,后16位为“低位”.将它的高低位交换, ...

  2. 关于grub的那些事(二)

    上回说到/etc/default/grub文件,我直接抄了人家的文章,感觉那Wiki确实写的很详细,所以就用上拿来主义了. 这次是分析该文件,因为这是grub必读的文件,也记录着控制grub工作的环境 ...

  3. socket网络编程快速上手(一)

    工作以来,写了很多socket相关的代码.磕磕碰碰,走了很多弯路,也积累了一些东西,今天正好整理一下.为了证明不是从书上抄来的,逻辑会有点乱(借口,呵呵)!知识点的介绍也不会像书上说的那么详细和精准, ...

  4. 应用程序入口 WSGIHandler

    Django 源码小剖: 应用程序入口 WSGIHandler WSGI 有三个部分, 分别为服务器(server), 应用程序(application) 和中间件(middleware). 已经知道 ...

  5. Select * 一定不走索引是否正确?

    Select * 一定不走索引是否正确? 走索引指的是:SQL语句的执行计划用到了1.聚集索引查找  2.索引查找  ,并且查询语句中需要有where子句 根据where子句的过滤条件,去聚集索引或非 ...

  6. JS获取table表格任意单元格值

    jsp页面表格布局 <body onload="show()"> <center> <input type="text" valu ...

  7. 通过实体反射实现CriteriaQuery并列条件查询

    将实体反射之后获取查询字段的值,并添加到Predicate对象数组中 public Predicate getPredicateAnd(T entity, Root<T> root, Cr ...

  8. Windows应用商店API

    Windows应用商店API 动手实验 实验 8: Windows应用商店API 2012年9月 简介 编写Windows应用商店应用最令人瞩目的理由之一是您可以方便地将它们发布到Windows应用商 ...

  9. hdu1205(类似 分布垃圾数列)

    Problem Description A Fibonacci sequence is calculated by adding the previous two members the sequen ...

  10. Nginx学习之十四-GDB调试Nginx初试

    本文的测试环境: Win7+虚拟机VMWareVMware-workstation-full-7.1.4-385536+Ubuntu12.04 Nginx-1.4.0 要想有效的研究Nginx源码,必 ...