HDU 5877 Weak Pair 2016 ACM/ICPC Asia Regional Dalian Online(树状数组+离散化)

来源:互联网 发布:源码基地 编辑:程序博客网 时间:2024/05/22 05:26

Weak Pair

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

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: 5876 5875 5874 5873 5872

题意是给你一棵树,树上有两点u,v u是v的祖先同时au*av<=K这样的一对点就是weak pair问的是这棵树上一共有多少队这样的点。
首先我们可以用dfs去遍历一下树,题目里要求的祖先一定会先被遍历到。所以在dfs过程中,每当我们遇到一个新的点,我们就将他与他所有的祖先配对,更新答案。这个东西可以用树状数组维护,每次查询有多少个符合weak pair au*av<=K的祖先节点。当某个点没有孩子节点了,就把这个节点的权从树状数组中删掉。所以树状数组中存储的永远都是某个点全部祖先的情况,不会出现不是他的祖先的情况,等于完成了自动配对。

#include "cstring"#include "iostream"#include "cstdio"#include "string.h"#include "vector"#include "algorithm"using namespace std;#define MAX 100005typedef struct node{    int id;    long long weight;}node;long long n,k;vector<node>list[MAX];node num[MAX];vector<long long> l;long long ans;long long c[MAX];int incnt[MAX];int lowbit(int x){    return x&(-x);}void add(int i,long long w){    while (i <= n)    {        c[i] += w;        i = i + lowbit(i);    }}long long Sum(int n){    long long sum = 0;    while (n>0)    {        sum += c[n];        n = n - lowbit(n);    }    return sum;}void dfs(int root){    long long require=k/num[root].weight;    int id=upper_bound(l.begin(),l.end(),require)-l.begin();    if(l[id]==require)        id--;    ans+=Sum(id);    id=lower_bound(l.begin(),l.end(),num[root].weight)-l.begin()+1;    add(id,1);    for(int i=1;i<=list[root].size();i++)    {        dfs(list[root][i-1].id);    }    add(id,-1);}void init(){    memset(c,0,sizeof(c));    memset(incnt,0,sizeof(incnt));    l.clear();    ans=0;    for(int i=1;i<=n;i++)        list[i].clear();}int main(){    int cas;    scanf("%d",&cas);    while(cas--)    {        init();        scanf("%lld%lld",&n,&k);        for(int i=1;i<=n;i++)        {            long long weight;            scanf("%lld",&weight);            node temp;            temp.weight=weight;            temp.id=i;            num[i]=temp;            l.push_back(weight);        }        sort(l.begin(),l.end());        l.erase(unique(l.begin(),l.end()),l.end());        for(int i=1;i<=n-1;i++)        {            int u,v;            scanf("%d%d",&u,&v);            list[u].push_back(num[v]);            incnt[v]++;        }        int root;        for(int i=1;i<=n;i++)        {            if(incnt[i]==0)            {                root=i;                break;            }        }        dfs(root);        printf("%lld\n",ans);    }}
0 0
原创粉丝点击