zoukankan      html  css  js  c++  java
  • P3605 [USACO17JAN]Promotion Counting P

    线段树合并裸题。线段树的下标维护的是能力指数,需要离散化。统计答案可以在线段树上查询后缀和。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    const int N = 1e5 + 100;
    struct Edge {
    	int v, nxt;
    } e[N << 1];
    struct Node {
    	int lc, rc;
    	int v;
    } tr[N * 21];
    vector<int> vec;
    int a[N], n, m, cnt, idx, ans[N], head[N], root[N]; 
    
    int get(int x) {
    	return lower_bound(vec.begin(), vec.end(), x) - vec.begin(); 
    }
    
    void Add(int u, int v) {
    	e[++cnt].v = v;
    	e[cnt].nxt = head[u];
    	head[u] = cnt;
    } 
    
    void pushup(int u) {
    	tr[u].v = tr[tr[u].lc].v + tr[tr[u].rc].v;
    }
    
    void insert(int u, int l, int r, int k, int v) {
    	if( l == r) {
    		tr[u].v += v;
    		return;
    	}
    	int mid = l + r >> 1;
    	if(k <= mid) {
    		if( !tr[u].lc)	tr[u].lc = ++ idx;
    		insert(tr[u].lc, l, mid, k, v);
    	}
    	else {
    		if( !tr[u].rc)  tr[u].rc = ++ idx;
    		insert(tr[u].rc, mid + 1, r, k, v);
    	}
    	pushup(u);
    } 
    
    int query(int u, int l, int r, int k) {//查询后缀和  
    	if( l >= k) {
    		return tr[u].v;
    	}
    	int mid = l + r >> 1;
    	int res = 0;
    	if( k <= mid) {
    		if(tr[u].lc)
    			res += query(tr[u].lc, l, mid, k);
    	}
    	if( tr[u].rc)
    		res += query(tr[u].rc, mid + 1, r, k);
    	return res;
    }
    
    int merge(int p, int q, int l, int r) {
    	if( !p || !q)
    		return p + q;
    	if( l == r) {
    		tr[p].v += tr[q].v;
    		return p;
    	}
    	int mid = l + r >> 1;
    	tr[p].lc = merge(tr[p].lc, tr[q].lc, l, mid);
    	tr[p].rc = merge(tr[p].rc, tr[q].rc, mid + 1, r);
    	pushup(p);
    	return p;
    } 
    
    void dfs(int u) {
    	for(int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].v;
    		dfs(v);
    		root[u] = merge(root[u], root[v], 1, (int)vec.size());
    	}
    	ans[u] = query(root[u], 1, (int)vec.size(), a[u]) - 1;
    } 
    
    int main()
    {
    	scanf("%d", &n);
    	for(int i = 1; i <= n; i ++)
    		root[i] = i;
    	idx = n;
    	for(int i = 1; i <= n; i ++) {
    		scanf("%d", &a[i]);
    		vec.push_back(a[i]);
    	}
    	sort(vec.begin(), vec.end());
    	vec.erase(unique(vec.begin(), vec.end()), vec.end());
    	for(int i = 1; i <= n; i ++) {
    		a[i] = get(a[i]) + 1;
    		insert(root[i], 1, (int)vec.size(), a[i], 1);
    	}
    	for(int i = 2; i <= n; i ++) {
    		int x; 
    		scanf("%d", &x);
    		Add(x, i);
    	}
    	dfs(1);
    	for(int i = 1; i <= n; i ++)
    	    printf("%d
    ", ans[i]);
    	return 0;
    } 
    
  • 相关阅读:
    了解HDD或SDD磁盘的健康状态
    修复丢失的打开方式
    Invoke-WebRequest : 请求被中止: 未能创建 SSL/TLS 安全通道。
    绕过禁止未登陆用户访问
    debug
    更新已有数据
    编码格式(乱码)
    ajax
    Http
    科学的管理和规范标准
  • 原文地址:https://www.cnblogs.com/wyy0804/p/13773332.html
Copyright © 2011-2022 走看看