zoukankan      html  css  js  c++  java
  • hdu 5877(树状数组+dfs)

    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 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×avk.

    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:
      
      1N105
      
      0ai109
      
      0k1018
     
    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;
    }
  • 相关阅读:
    centos 安装 谷歌BBR
    centos上mailx通过465端口发送邮件
    centos 6的LAMP一键安装包(可选择/升级版本)
    Linux 一键安装最新内核并开启 BBR 脚本
    CentOS 7安装Xfce和VNC
    重构手法之简化函数调用【4】
    重构手法之简化函数调用【3】
    重构手法之简化函数调用【2】
    重构手法之简化函数调用【1】
    重构手法之简化条件表达式【4】
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5877279.html
Copyright © 2011-2022 走看看