Weak Pair
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2387 Accepted Submission(s): 740
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 ord 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?
(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
0≤ai≤109
0≤k≤1018
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
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
满足第一个条件的话进行DFS,然后统计父亲节点里面满足 val <= k/a[u] 的个数.这里可以用 树状数组进行维护.
///pro do this : a[l]%a[l+1]%...%a[r] #include <stdio.h> #include <iostream> #include <algorithm> #include <queue> #include <string.h> #include <vector> using namespace std; typedef long long LL; const int N = 200005; const LL INF = 1e19; LL a[N],b[N],c[N]; int cnt,n,m; int indegree[N]; struct Edge{ int v,next; }edge[N]; int head[N],tot; LL ans,k; void addEdge(int u,int v,int &k){ edge[k].v = v,edge[k].next = head[u],head[u] = k++; } void init(){ tot = 0,ans = 0; memset(head,-1,sizeof(head)); memset(indegree,0,sizeof(indegree)); memset(c,0,sizeof(c)); } int lowbit(int x){ return x&(-x); } void update(int v,int idx){ for(int i=idx;i<=cnt;i+=lowbit(i)){ c[i] += v; } } LL getsum(int idx){ LL ans=0; for(int i=idx;i>=1;i-=lowbit(i)){ ans+=c[i]; } return ans; } void dfs(int u){ int x = upper_bound(b+1,b+cnt+1,k/a[u])-b-1; ///upper_bound 第一个大于当前元素的第一个数的下标. int pos = lower_bound(b+1,b+cnt+1,a[u])-b; ///寻找离散化之后的下标 ans+=getsum(x); update(1,pos); for(int i=head[u];i!=-1;i=edge[i].next){ dfs(edge[i].v); } update(-1,pos); } int main(){ int tcase; scanf("%d",&tcase); while(tcase--){ init(); scanf("%d%lld",&n,&k); m = 0; for(int i=1;i<=n;i++){ scanf("%lld",&a[i]); b[++m] = a[i]; if(a[i]==0) b[++m] = INF; else b[++m] = k/a[i]; } sort(b+1,b+m+1); cnt = unique(b+1,b+m+1)-(b+1); for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); addEdge(u,v,tot); indegree[v]++; } for(int i=1;i<=n;i++){ if(indegree[i]==0) dfs(i); } printf("%lld ",ans); } return 0; }