您的位置:首页 > 大数据 > 人工智能

Weak Pair HDU - 5877

2017-05-14 15:16 246 查看
You are given a rootedrooted tree of NN nodes, labeled from 1 to NN. To the iith node a non-negative value aiai is assigned.An orderedordered pair of nodes (u,v)(u,v) is said to be weakweak if

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

(2) au×av≤kau×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 TT denoting number of test cases.

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

The second line contains NN space-separated integers, denoting a1a1 to aNaN.

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

Constrains:

1≤N≤1051≤N≤105

0≤ai≤1090≤ai≤109

0≤k≤10180≤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

题意:让你求满足条件的有多少个点对。这题目感觉题意也写得不是很清楚啊。。。到底是满足任意一个还是都要满足2333。。。是我蠢么。。

条件是 u是v的父节点,然后 uv的权值乘积要小于一个定值k。。

思路:怎么保证u是v的父节点呢。那你走dfs,必定是从父节点走到儿子节点的。。所以在走dfs的时候更新查询靠谱。那对一个u怎么确定有多少v呢。首先 我们知道我们要的值必定是 k/w[u] ,如果v的值小于这个说明这个v是可以的,那我们可以把一个权值拆成本身w 和 k/w 组成一个新数组,之后根据大小关系离散化,这样就很明显是单点更新区间查询了,那我们就又要搞一搞树状数组了。然后我们再来讲讲上面那个u怎么确定有多少个v 这个思路是我一开始的思路,嗯。。。是错的2333(错的你还写??) 错在哪呢,。。你这样写你会发现你消除不了之前子树的影响。。也许能?能要不留个言?2333 但是你可以统计这个子节点之前有多少个u是满足的,这是个相对的关系嘛。。一样的,然后你每次先更新父节点然后dfs退栈之前消除影响

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<vector>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<set>
using namespace std;

//thanks to pyf ...

#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define mp(x,y) make_pair(x,y)
typedef pair<int, int> PII;
typedef long long ll;

const int N = 1e6 + 5;

struct Edge
{
int u, v, next;
} edge
;
int head
;
int tot = 0;
int indeg
;
ll BIT
;
ll w
;
ll opt_w[N * 2];
ll k;
ll ans = 0;
map<ll, int>m;
int n;
void init()
{
CLR(indeg, 0);
CLR(w,
b951
0);
CLR(opt_w, 0);
CLR(BIT, 0);
CLR(head, -1);
m.clear();
ans = 0;
tot = 0;
}
int lowbit(int x)
{
return x & (-x);
}
void update(int pos, ll val)
{
while (pos <= 2 * n)
{
BIT[pos] += val;
pos += lowbit(pos);
}
}
ll query(int pos)
{
ll res = 0;
while (pos > 0)
{
res += BIT[pos];
pos -= lowbit(pos);
}
return res;
}
void add_edge(int u, int v)
{
edge[tot].u = u;
edge[tot].v = v;
edge[tot].next = head[u];
head[u] = tot ++;
}
void dfs(int u)
{
ans += query(m[k / w[u]]);
update(m[w[u]], 1);
for (int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v ;
//  cout << u << " " << v << " " << i << " " << edge[i].next << endl;
dfs(v);
}
update(m[w[u]], - 1);
}
int main()
{
int T;
while (scanf("%d", &T) == 1)
{
while (T--)
{
init();
scanf("%d%lld", &n, &k);
for (int i = 1; i <= n; i++)
{
scanf("%lld", w + i);
opt_w[i] = w[i];
if (w[i] == 0)
opt_w[n + i] = INF;
else
opt_w[n + i] = k / w[i];
}
for (int i = 1; i < n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
indeg[v] ++ ;
add_edge(u, v);
//      add_edge(v, u);
}
sort(opt_w + 1, opt_w + 1 + n * 2);
for (int i = 1; i <= n * 2; i++)
m[opt_w[i]] = i;
for (int i = 1; i <= n; i++)
if (!indeg[i])
dfs(i);
printf("%lld\n", ans);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: