zoukankan      html  css  js  c++  java
  • bzoj4756 [Usaco2017 Jan]Promotion Counting

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4756

    【题解】

    dsu on tree,树状数组直接上

    O(nlog^2n)

    # include <vector>
    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 2e5 + 10, N = 4e5 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    int n, a[M]; 
    vector<int> ps;
    int ans[M];
    
    int head[M], nxt[M], to[M], tot=0;
    inline void add(int u, int v) {
        ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
    }
    
    # define lb(x) (x&(-x))
    struct BIT {
        int c[N];
        inline void edt(int x, int d) {
            for (; x<=n; x+=lb(x)) c[x] += d;
        }
        inline int sum(int x) {
            int ret = 0;
            for (; x; x-=lb(x)) ret += c[x];
            return ret;
        }
        inline int sum(int x, int y) {
            if(x>y) return 0;
            return sum(y) - sum(x-1);
        }
    }T;
    # undef lb
    
    int sz[M];
    inline void dfssize(int x) {
        sz[x] = 1;
        for (int i=head[x]; i; i=nxt[i]) {
            dfssize(to[i]);
            sz[x] += sz[to[i]];
        }
    }
    
    bool big[M];
    inline void dfsans(int x) {
        T.edt(a[x], 1);
        for (int i=head[x]; i; i=nxt[i]) 
            if(!big[to[i]]) dfsans(to[i]);
    }
    
    inline void delans(int x) {
        T.edt(a[x], -1);
        for (int i=head[x]; i; i=nxt[i])
            if(!big[to[i]]) delans(to[i]);
    }
    
    inline void dsu(int x, bool iskep) {
        int mx = -1, bigc = -1;
        for (int i=head[x]; i; i=nxt[i]) 
            if(sz[to[i]] > mx) mx = sz[to[i]], bigc = to[i];
        for (int i=head[x]; i; i=nxt[i]) 
            if(to[i] != bigc) dsu(to[i], 0);
        if(bigc != -1) big[bigc] = 1, dsu(bigc, 1);
        dfsans(x);
        ans[x] = T.sum(a[x]+1, n);
        if(bigc != -1) big[bigc] = 0;
        if(!iskep) delans(x);            
    }
            
    
    int main() {
        cin >> n;
        for (int i=1; i<=n; ++i) {
            scanf("%d", &a[i]);
            ps.push_back(a[i]);
        }
        
        sort(ps.begin(), ps.end());
        ps.erase(unique(ps.begin(), ps.end()), ps.end());
        
        for (int i=1; i<=n; ++i) a[i] = lower_bound(ps.begin(), ps.end(), a[i]) - ps.begin() + 1;
    
        
        for (int i=2, fa; i<=n; ++i) {
            scanf("%d", &fa);
            add(fa, i);
        }
        
        dfssize(1);
        dsu(1, 1);
        
        for (int i=1; i<=n; ++i) printf("%d
    ", ans[i]);
        
        return 0;
    }
    View Code
  • 相关阅读:
    Cisco静态路由
    VTP
    trunk
    vim中文乱码
    Ubuntu 切换root用户是时出现su Authentication failure
    github 换行符自动转换功能
    Qt弹出消息对话框
    串口发送Hex数组
    Qt 按顺序保存多个文件
    Qt乱码解决办法(常量中有换行符)
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj4756.html
Copyright © 2011-2022 走看看