zoukankan      html  css  js  c++  java
  • HDU5877 Weak Pair

    题目链接 Weak Pair

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

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

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

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #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
    
    const int N     =    300000      +       10;
    
    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;
    
    }
    
  • 相关阅读:
    AcWing 3302. 表达式求值
    AcWing 828. 模拟栈
    六种风格时间显示
    web2.0常用配色.
    CSS浏览器兼容问题详解
    jQuery Cycle Plugin Beginner Demos
    jQuery插件Clipboard Copy(复制)。
    精通jQuery选择器使用
    jQuery插件右下角弹出信息
    CSS关于box(盒模式)的一系列问题
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/6352081.html
Copyright © 2011-2022 走看看