zoukankan      html  css  js  c++  java
  • HDU5877Weak Pair

                                                    Weak Pair

                                    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
                                             


    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


    题意十分明确, 就是求出符合题意的有序点对个数。

    首先对ai离散,离散之后的结果用rk[i]表示,然后进行二分预处理得到f[i],其中f[i]的意义为:其他的点和i这个节点满足weakpair要求的权值最大名次(名次权值小的排在前面)。

    然后就开始跑一遍DFS,树状数组维护一下答案,就好了。


    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define REP(i,n)                for(int i(0); i <  (n); ++i)
    #define rep(i,a,b)              for(int i(a); i <= (b); ++i)
    #define dec(i,a,b)              for(int i(a); i >= (b); --i)
    #define for_edge(i,x)           for(int i = H[x]; i; i = X[i])
    
    #define LL      long long
    #define ULL     unsigned long long
    #define MP      make_pair
    #define PB      push_back
    #define FI      first
    #define SE      second
    #define INF     1 << 30
    
    const int N     =    300000      +       10;
    const int M     =    10000       +       10;
    const int Q     =    1000        +       10;
    const int A     =    30          +       1;
    
    
    struct Node{
    	LL num;
    	int id;
    	friend bool operator < (const Node &a, const Node &b){
    		return a.num < b.num;
    	}
    } tree[N];
    
    int E[N << 1], X[N << 1], H[N << 1];
    LL a[N];
    int T, et;
    int n;
    LL k;
    int x, y;
    LL rk[N], f[N];
    LL now;
    int l, r;
    bool pa[N];
    int root;
    LL c[N];
    LL ans;
    bool v[N];
    
    inline void addedge(int a, int b){
    	E[++et] = b, X[et] = H[a], H[a] = et;
    }
    
    inline void add(LL x, LL val){ 
    	for (; x <= n; x += (x) & (-x)) 
    		c[x] += val;
    }
    
    inline LL query(LL x){
    	LL ret(0); 
    	for (; x; x -= (x) & (-x)) ret += c[x]; 
    	return ret;
    }
    
    void dfs(int x){
    	add(rk[x], 1);
    	for_edge(i, x) if (!v[E[i]]) dfs(E[i]), v[E[i]] = true;
    	add(rk[x], -1);
    	ans += query(f[x]);
    }
    
    
    int main(){
    
    	scanf("%d", &T);
    	while (T--){
    		et = 0;
    		scanf("%d%lld", &n, &k);
    		rep(i, 1, n) scanf("%lld", a + i);
    		memset(v, false, sizeof v);
    		memset(pa, true, sizeof pa);
    		memset(tree, 0, sizeof tree);
    		memset(H, 0, sizeof H);
    		rep(i, 1, n - 1){
    			scanf("%d%d", &x, &y);
    			addedge(x, y);
    			pa[y] = false;
    		}
    
    		rep(i, 1, n){
    			tree[i].num = a[i];
    			tree[i].id = i;
    		}
    
    		sort(tree + 1, tree + n + 1);
    		rk[tree[1].id] = 1;
    		rep(i, 2, n) 
    			if (tree[i].num == tree[i - 1].num) rk[tree[i].id] = rk[tree[i - 1].id];
    			else rk[tree[i].id] = rk[tree[i - 1].id] + 1;
    
    		rep(i, 1, n){
    			now = k / a[i];
    			l = 1; r = n;
    			if (tree[1].num > now) f[i] = 0; 
    			else{	
    				while (l + 1 < r){
    					int mid = (l + r) >> 1;
    					if (tree[mid].num <= now) l = mid;
    					else r = mid - 1;
    				}
    
    				if (tree[r].num <= now) l = r;
    				f[i] = rk[tree[l].id];
    			}
    
    		}
    		root = 0;
    		rep(i, 1, n) if (pa[i]){ root = i; break;}
    		memset(c, 0, sizeof c);
    		ans = 0;
    		v[root] = true;
    		dfs(root);
    		printf("%lld
    ", ans);
    
    
    	}
    
    
    
    	return 0;
    
    }
    
    
    




  • 相关阅读:
    bzoj 3993: [SDOI2015]星际战争
    bzoj 4066: 简单题
    bzoj 3611: [Heoi2014]大工程
    bzoj 3530: [Sdoi2014]数数
    bzoj 3529: [Sdoi2014]数表
    bzoj 3504: [Cqoi2014]危桥
    bzoj 3489: A simple rmq problem
    bzoj 3211: 花神游历各国
    bzoj 3196: Tyvj 1730 二逼平衡树
    bzoj 3172: [Tjoi2013]单词
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/6648795.html
Copyright © 2011-2022 走看看