正难则反的思想还是不能灵活应用啊

题意:给你n个点,每个点有一个权值,接着是n-1有向条边形成一颗有根树,问你有多少对点的权值乘积小于等于给定的值k,其中这对点必须是孩子节点与祖先的关系

我们反向思考,可以知道任一点都只对其每个祖先有贡献。所以我们可以转化为求每个点与其每个祖先的乘积小于等于给定的值k的对数。

我们dfs遍历这颗树使用树状数组维护,dfs遍历孩子就添点回溯就删点,接着对每个点计算树状数组里不大于(k/此点)的个数。注意值太大我们需要离散化,而且我们可以把每个点m与k/m都离散化出来,然后就是每次树状数组更新这个点的个数(加减1),查询不大于(k/此点)的个数

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const double Pi=acos(-1.0);
const int Mod=1e9+;
const int Max=;
struct node
{
int pos;
ll val;
} nod[Max];
int bit[Max],vis[Max],n;
ll k,ans,rop[Max];
int head[Max],nnext[Max],to[Max],e;
bool cmp(struct node p1,struct node p2)
{
if(p1.val==p2.val)
return p1.pos<p2.pos;
return p1.val<p2.val;
}
void Add(int u,int v)
{
to[e]=v;
nnext[e]=head[u];
head[u]=e++;
return;
}
int lowbit(int x)
{
return x&(-x);
}
void AddBit(int x,int y)
{
while(x<=(n<<))
{
bit[x]+=y;
x+=lowbit(x);
}
return;
}
int Sum(int x)
{
int sum=;
while(x)
{
sum+=bit[x];
x-=lowbit(x);
}
return sum;
}
void dfs(int son,int fat)
{
AddBit(rop[son],);//遍历孩子添边
for(int i=head[son]; i!=-; i=nnext[i])
{
if(to[i]!=fat)
{
ans+=Sum(rop[to[i]+n]);
dfs(to[i],son);
}
}
AddBit(rop[son],-);//回溯删边
return;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(vis,,sizeof(vis));
scanf("%d %I64d",&n,&k);
for(int i=; i<=n; ++i)
{
scanf("%I64d",&nod[i].val);
nod[i].pos=i;
}
for(int i=; i<=n; ++i)//和k/num[u]一起离散化
{
if(nod[i].val)//关键注意除数为0
nod[i+n].val=k/nod[i].val;
else
nod[i+n].val=0ll;
nod[i+n].pos=i+n;
}
sort(nod+,nod++(n<<),cmp);
for(int i=; i<=(n<<); ++i)//离散化
rop[nod[i].pos]=i;
e=;
memset(head,-,sizeof(head));
int u,v;
for(int i=; i<n; ++i)
{
scanf("%d %d",&u,&v);
Add(u,v);
vis[v]++;
}
ans=0ll;
memset(bit,,sizeof(bit));
for(int i=; i<=n; ++i)
{
if(!vis[i])//找根
{
dfs(i,i);
}
}
printf("%I64d\n",ans);
}
return ;
}

Weak Pair

HDU 5877 Weak Pair (2016年大连网络赛 J dfs+反向思维)的更多相关文章

  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. 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  ...

  4. hdu 5877 Weak Pair (Treap)

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. hihocoder 1279(状压)

    坑爹的题目.不过不能说不是一道挺好的题目. 坑主要坑在,妹的我一样的复杂度,写的姿势略差了点然后就一直超时. 比赛的时候我还直接就看错题目,把AND运算看成了OR...还敲完交了一发. 这题很容易想到 ...

  2. 前端Js传递数组至服务器端

    $("#delete").click(function () { var ID = ""; var ary = []; var bb = document.ge ...

  3. Markov Process

    w Markov Process -- from Wolfram MathWorld  http://mathworld.wolfram.com/MarkovProcess.html 谷歌背后的数学_ ...

  4. Man-in-the-middle attack

    w https://en.wikipedia.org/wiki/Man-in-the-middle_attack https://zh.wikipedia.org/wiki/中间人攻击 需要通过一个安 ...

  5. 常用的数据库sql语句

    create table query_audit_log(Time varchar(255) default null,Id int(10) default null, Command varchar ...

  6. Vue.js之组件传值

    Vue.js之组件传值 属性传值可以从父组件到子组件,也可以从子组件到父组件. 这里讲一下从父组件到子组件的传值 还以上次的demo为例,demo里有APP.vue是父组件,Header.vue,Us ...

  7. python requests 使用

    快速上手 迫不及待了吗?本页内容为如何入门 Requests 提供了很好的指引.其假设你已经安装了 Requests.如果还没有,去安装一节看看吧. 首先,确认一下: Requests 已安装 Req ...

  8. 画图-drawpoint and drawpath

    版权声明:本文因海牛宝宝童鞋才疏学浅,可能晦涩难懂,但也是呕心沥血之作,麻烦转载的时候留个申明. https://blog.csdn.net/u012321815/article/details/26 ...

  9. Spring学习笔记1—依赖注入(构造器注入、set注入和注解注入)

    什么是依赖注入 在以前的java开发中,某个类中需要依赖其它类的方法时,通常是new一个依赖类再调用类实例的方法,这种方法耦合度太高并且不容易测试,spring提出了依赖注入的思想,即依赖类不由程序员 ...

  10. 鸟哥的Linux私房菜-第一部分-第3章主机规划与磁盘分区

    1. 选择一个与你的Linux搭配的主机配置 NAT服务器:小型企业或者学校都基本是只有一条对外的线路,网卡 SAMBA服务器:完成Windows网上邻居的功能,网卡和硬盘要求高 Mail服务器:如果 ...