Weak Pair

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 5985    Accepted Submission(s): 1683


 

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

​2016 ACM/ICPC Asia Regional Dalian Online​

 

 

Recommend

wange2014   |   We have carefully selected several similar problems for you:  ​​6667​​​ ​​6666​​​ ​​6665​​​ ​​6664​​​ ​​6663​​ 

 

 

​Statistic​​​ | ​​Submit​​​ | ​​Discuss​​​ | ​​Note​

 

题意:

weak pair的要求:

1.u是v的祖先(注意不一定是父亲)

2.val[u]*val[v] <=k;

问有多对?

分析:

val[u]<=k/val[v],对于当前节点来说,即祖先节点有多少满足小于 k/val[u],利用dfs的特性建立树状数组,一看代码就懂。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef long long ll;
typedef unsigned long long ULL;
const int N=500005;
LL val[N],c[N];
int in[N];
vector<int>G[N];
vector<LL>v;
int n,m;
LL k;
int lowbit(int x)
{
return x & -x;
}
ll sum(int x) //树状数组 前缀和查询
{
ll sum = 0;
while(x)
{
sum += c[x];
x -= lowbit(x);
}
return sum;
}
void add(int x, ll val) //树状数组 单点修改
{
while(x <= m)
{
c[x] += val;
x += lowbit(x);
}
}

LL ans=0;
int getid(LL x)
{
return lower_bound(v.begin(),v.end(),x)-v.begin()+1;
}
void dfs(int u)
{

for(int i=0; i<G[u].size(); i++)
{
int v=G[u][i];
if(val[v]==0)
ans+=sum(getid(1e18));
else
ans+=sum(getid(k/val[v]));

add(getid(val[v]),1);
dfs(v);
add(getid(val[v]),-1);

}
}

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(c,0,sizeof(c));
v.clear();
ans=0;

scanf("%d%lld",&n,&k);


for(int i=1; i<=n; i++)
{
in[i]=0;
G[i].clear();
scanf("%lld",&val[i]);
v.push_back(val[i]);
if(val[i]==0)
{
v.push_back(1e18);
}
else
v.push_back(k/val[i]);
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
m=v.size();



int u,v;
for(int i=1; i<n; i++)
{
scanf("%d%d",&u,&v);
G[u].push_back(v);
in[v]++;
}

int root=1;
for(int i=1; i<=n; i++)
{
if(in[i]==0)
{
root=i;
break;
}
}

if(val[root]==0)
add(getid(1e18),1);
else
{

add(getid(val[root]),1);
}

//cout<<ans<<endl;
dfs(root);
printf("%lld\n",ans);

}

return 0;
}