您的位置:首页 > 其它

hdu 5877(树状数组+dfs)

2016-09-16 21:30 141 查看

Weak Pair

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


[align=left]Problem Description[/align]
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?

[align=left]Input[/align]
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

[align=left]Output[/align]
For each test case, print a single integer on a single line denoting the number of weak pairs in the tree.

[align=left]Sample Input[/align]

1
2 3
1 2
1 2

[align=left]Sample Output[/align]

1

[align=left]Source[/align]
2016 ACM/ICPC Asia Regional Dalian Online

满足第一个条件的话进行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
,b
,c
;
int cnt,n,m;
int indegree
;
struct Edge{
int v,next;
}edge
;
int head
,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\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: