zoukankan      html  css  js  c++  java
  • Gym 102861E E. Party Company

    很容易想到离线的做法,倍增往上找,然后整个dfs一遍,但是需要用到树状数组

    顺便,求log2(x)千万别写log(x) / log(2),精度会出问题,直接写log2(x)就行了

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 10;
    int age[N], maxn[N][21], fa[N][21], dep[N], ans[N];
    vector < int > v[N], point[N];
    
    void dfs1(int u, int f) {
        dep[u] = dep[f] + 1;
        fa[u][0] = f; maxn[u][0] = max(age[u], age[f]);
        for (int i = 1; i <= 20; i++) {
            maxn[u][i] = max(maxn[u][i - 1], maxn[fa[u][i - 1]][i - 1]);
            fa[u][i] = fa[fa[u][i - 1]][i - 1];
        }
        for (int i = 0; i < v[u].size(); i++) {
            int e = v[u][i];
            if (e != f)
                dfs1(e, u);
        }
    }
    
    int c[N];
    
    inline int lowbit(int x) {
        return x & (-x);
    }
    
    inline void add(int pos, int val) {
        for (int i = pos; i < N; i += lowbit(i))
            c[i] += val;
    }
    
    inline int query(int val) {
        int ans = 0;
        for (int i = val; i > 0; i -= lowbit(i))
            ans += c[i];
        return ans;
    }
    
    void dfs(int u, int f) {
        for (int i = 0; i < point[u].size(); i++) {
            int e = point[u][i];
            add(e, 1);
        }
        ans[u] = query(age[u]);
        for (int i = 0; i < v[u].size(); i++) {
            int e = v[u][i];
            if (e == f)    continue;
            dfs(e, u);
        }
        for (int i = 0; i < point[u].size(); i++) {
            int e = point[u][i];
            add(e, -1);
        }
    }
    
    int main() {
        int n, m;
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= n; i++) {
            int a, b;
            scanf("%d %d", &a, &b);
            age[i] = a;
            v[b].push_back(i);
        }
        dfs1(1, 1);
        for (int i = 1; i <= m; i++) {
            int o, l, r;
            scanf("%d %d %d", &o, &l, &r);
            int p = o;
            if (o == 1)    {
                point[o].push_back(l);
                continue;
            }
            int sz = log2(dep[o] - 1);
            for (int j = sz; j >= 0; j--) {
                if (maxn[p][j] <= r)
                    p = fa[p][j];
            }
            point[p].push_back(l);
        }
        dfs(1, 1);
        for (int i = 1; i <= n; i++)
            printf("%d ", ans[i]);
        return 0;
    }
  • 相关阅读:
    使用强名称为程序集签名
    使用SN.exe对.Net生成的程序集进行签名
    .Net 程序集 签名工具sn.exe 密钥对SNK文件 最基本的用法
    MongoDB查询
    mongo批量写入es
    用 Spark 处理复杂数据类型(Array、Map、JSON字符串等)
    kafka消费者
    kafka生产者
    Pyspark常用API总结
    selenium+chromedriver+python3 不加载图片
  • 原文地址:https://www.cnblogs.com/cminus/p/14093524.html
Copyright © 2011-2022 走看看