Weak Pair

                                Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)

                                         

Problem Description
You are given a rooted
tree of N
nodes, labeled from 1 to N.
To the ith
node a non-negative value ai
is assigned.An ordered
pair of nodes (u,v)
is said to be weak
if

  (1) u
is an ancestor of v
(Note: In this problem a node u
is not considered an ancestor of itself);

  (2) au×av≤k.



Can you find the number of weak pairs in the tree?
 
Input
There are multiple cases in the data set.

  The first line of input contains an integer T
denoting number of test cases.

  For each case, the first line contains two space-separated integers,
N
and k,
respectively.

  The second line contains N
space-separated integers, denoting a1
to aN.

  Each of the subsequent lines contains two space-separated integers defining an edge connecting nodes
u
and v
, where node u
is the parent of node v.



  Constrains:

  

  1≤N≤105


  

  0≤ai≤109


  

  0≤k≤1018
 
Output
For each test case, print a single integer on a single line denoting the number of weak pairs in the tree.
 
Sample Input
1
2 3
1 2
1 2
 
Sample Output
1
 
Source

题意十分明确, 就是求出符合题意的有序点对个数。

首先对ai离散,离散之后的结果用rk[i]表示,然后进行二分预处理得到f[i],其中f[i]的意义为:其他的点和i这个节点满足weakpair要求的权值最大名次(名次权值小的排在前面)。

然后就开始跑一遍DFS,树状数组维护一下答案,就好了。

#include <bits/stdc++.h>

using namespace std;

#define REP(i,n)                for(int i(0); i <  (n); ++i)
#define rep(i,a,b) for(int i(a); i <= (b); ++i)
#define dec(i,a,b) for(int i(a); i >= (b); --i)
#define for_edge(i,x) for(int i = H[x]; i; i = X[i]) #define LL long long
#define ULL unsigned long long
#define MP make_pair
#define PB push_back
#define FI first
#define SE second
#define INF 1 << 30 const int N = 300000 + 10;
const int M = 10000 + 10;
const int Q = 1000 + 10;
const int A = 30 + 1; struct Node{
LL num;
int id;
friend bool operator < (const Node &a, const Node &b){
return a.num < b.num;
}
} tree[N]; int E[N << 1], X[N << 1], H[N << 1];
LL a[N];
int T, et;
int n;
LL k;
int x, y;
LL rk[N], f[N];
LL now;
int l, r;
bool pa[N];
int root;
LL c[N];
LL ans;
bool v[N]; inline void addedge(int a, int b){
E[++et] = b, X[et] = H[a], H[a] = et;
} inline void add(LL x, LL val){
for (; x <= n; x += (x) & (-x))
c[x] += val;
} inline LL query(LL x){
LL ret(0);
for (; x; x -= (x) & (-x)) ret += c[x];
return ret;
} void dfs(int x){
add(rk[x], 1);
for_edge(i, x) if (!v[E[i]]) dfs(E[i]), v[E[i]] = true;
add(rk[x], -1);
ans += query(f[x]);
} int main(){ scanf("%d", &T);
while (T--){
et = 0;
scanf("%d%lld", &n, &k);
rep(i, 1, n) scanf("%lld", a + i);
memset(v, false, sizeof v);
memset(pa, true, sizeof pa);
memset(tree, 0, sizeof tree);
memset(H, 0, sizeof H);
rep(i, 1, n - 1){
scanf("%d%d", &x, &y);
addedge(x, y);
pa[y] = false;
} rep(i, 1, n){
tree[i].num = a[i];
tree[i].id = i;
} sort(tree + 1, tree + n + 1);
rk[tree[1].id] = 1;
rep(i, 2, n)
if (tree[i].num == tree[i - 1].num) rk[tree[i].id] = rk[tree[i - 1].id];
else rk[tree[i].id] = rk[tree[i - 1].id] + 1; rep(i, 1, n){
now = k / a[i];
l = 1; r = n;
if (tree[1].num > now) f[i] = 0;
else{
while (l + 1 < r){
int mid = (l + r) >> 1;
if (tree[mid].num <= now) l = mid;
else r = mid - 1;
} if (tree[r].num <= now) l = r;
f[i] = rk[tree[l].id];
} }
root = 0;
rep(i, 1, n) if (pa[i]){ root = i; break;}
memset(c, 0, sizeof c);
ans = 0;
v[root] = true;
dfs(root);
printf("%lld\n", ans); } return 0; }

HDU5877Weak Pair的更多相关文章

  1. c++ pair 使用

    1. 包含头文件: #include <utility> 2. pair 的操作: pair<T1,T2> p; pair<T1,T2> p(v1,v2); pai ...

  2. 论Pair的重要性

    这些天我在用React和D3做图表,从已经实现的图表里复制了一些坐标轴的代码,发现坐标轴上的n个点里,只有第一个点下面能渲染出文字提示,其余点下面都无法渲染出文字. 和组里的FL一起百思不得其解好几天 ...

  3. 2016 ACM/ICPC Asia Regional Dalian Online 1010 Weak Pair dfs序+分块

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submissio ...

  4. pair的使用

    #include<iostream> #include<cmath> #include<cstdio> #include<algorithm> #inc ...

  5. 【C++】pair

    STL的pair,有两个值,可以是不同的类型. template <class T1, class T2> struct pair; 注意,pair在头文件utility中,不要inclu ...

  6. hackerrank Similar Pair

    传送门 Problem Statement You are given a tree where each node is labeled from 1 to n. How many similar ...

  7. uva12546. LCM Pair Sum

    uva12546. LCM Pair Sum One of your friends desperately needs your help. He is working with a secret ...

  8. C++标准库 -- pair

    头文件:<utility> 可访问属性: first 第一个值 second 第二个值 可访问方法: swap(pair) 和另外一个pair交换值 其他相关方法: make_pair(v ...

  9. 2016 大连网赛---Weak Pair(dfs+树状数组)

    题目链接 http://acm.split.hdu.edu.cn/showproblem.php?pid=5877 Problem Description You are given a rooted ...

随机推荐

  1. 关于IDEA 单元测试时 【empty test suite】异常的分析!!

    IDEA功能很强大,配置很操蛋,自从用了之后掉了很多坑!!! 这几天要用单元测试,方法完好但是就是一直报empty test suite ,WTF,类找不到 在网上反复的找答案都没有合适 静下心想想, ...

  2. android/libs/libammsdk.jar" already exists! 解决方法

    Error: Uh oh!"/work/2016/fengkongbao/.meteor/local/cordova-build/platforms/android/libs/libamms ...

  3. 数据预处理之独热编码(One-Hot Encoding)

    问题的由来 在很多机器学习任务中,特征并不总是连续值,而有可能是分类值. 例如,考虑以下三个特征: ["male","female"] ["from ...

  4. mysql基础查询

    #进阶1:基础查询/*语法:select:查询列表 from 表名; 类似于:System.out.println(打印的东西); 特点:1.查询列表可以是:表中的字段.常量值.表达式.函数2.查询的 ...

  5. 【Combinations】cpp

    题目: Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For ex ...

  6. C++文件读写之对象的读写

    这里以一个简单的学生信息管理系统为例. 首先是对象的建立,包括姓名,学号,成绩,学分,等 如下: 这里面包括两个子对象, class Student { public: Student() :scor ...

  7. pycharm许可证过期

    1.选择enter license 2.选择license server 3.输入http://idea.imsxm.com 4.点击ok 好,解决了

  8. Python+Selenium中级篇之-二次封装Selenium中几个方法

    本文来介绍,如何把常用的几个webdriver的方法封装到自己写的一个类中去,这个封装过程叫二次封装Selenium方法.我们把打开站点,浏览器前进和后退,关闭和退出浏览器这这个方法封装到一个新写的类 ...

  9. LuffyCity-MySQL综合练习50实例

    1.请创建如下表,并添加相应约束: 2.自行构造测试数据: 新建数据库 创建表 构造测试数据 #Step1-创建数据库LuffyCity_MySQL; #CREATE DATABASE LuffyCi ...

  10. Leetcode 503.下一个更大元素

    下一个更大元素 给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素.数字 x 的下一个更大的元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你 ...