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;
}

 

posted @ 2020-12-06 17:55  cminus  阅读(274)  评论(0编辑  收藏  举报