/ SeriousOJ /

Record Detail

Accepted


  
# Status Time Cost Memory Cost
#1 Accepted 1ms 344.0 KiB
#2 Accepted 1ms 532.0 KiB
#3 Accepted 48ms 592.0 KiB
#4 Accepted 46ms 616.0 KiB
#5 Accepted 47ms 788.0 KiB
#6 Accepted 55ms 860.0 KiB
#7 Accepted 53ms 788.0 KiB
#8 Accepted 71ms 2.52 MiB
#9 Accepted 72ms 2.52 MiB
#10 Accepted 66ms 3.52 MiB
#11 Accepted 28ms 8.52 MiB
#12 Accepted 66ms 20.91 MiB
#13 Accepted 68ms 20.77 MiB
#14 Accepted 68ms 20.93 MiB
#15 Accepted 67ms 20.867 MiB
#16 Accepted 68ms 20.934 MiB
#17 Accepted 64ms 20.777 MiB
#18 Accepted 65ms 20.938 MiB
#19 Accepted 68ms 15.27 MiB
#20 Accepted 64ms 15.27 MiB

Code

#include <bits/stdc++.h>
using namespace std;

struct Fenwick {
    int n;
    vector<int> bit;
    Fenwick(int n=0){ init(n); }
    void init(int n_){ n = n_; bit.assign(n+1, 0); }
    void add(int i, int delta){
        for(; i <= n; i += i & -i) bit[i] += delta;
    }
    int sumPrefix(int i){
        int s = 0;
        for(; i > 0; i -= i & -i) s += bit[i];
        return s;
    }
    int rangeSum(int l, int r){
        if(l>r) return 0;
        return sumPrefix(r) - sumPrefix(l-1);
    }
};

int N;
vector<vector<int>> g;
vector<int> A;
vector<int> sz, heavy, tin, tout, euler;
int timerdfs;
vector<int> cnt;     // frequency of values in current data structure
Fenwick bit;
vector<int> ans;

void dfs_sz(int u, int p){
    sz[u] = 1;
    tin[u] = ++timerdfs;
    euler[timerdfs] = u;
    heavy[u] = -1;
    int maxsz = 0;
    for(int v : g[u]) if(v != p){
        dfs_sz(v, u);
        sz[u] += sz[v];
        if(sz[v] > maxsz){ maxsz = sz[v]; heavy[u] = v; }
    }
    tout[u] = timerdfs;
}

inline void add_node(int node){
    int val = A[node];
    if(cnt[val] == 0) bit.add(val, 1);
    cnt[val]++;
}

inline void remove_node(int node){
    int val = A[node];
    cnt[val]--;
    if(cnt[val] == 0) bit.add(val, -1);
}

void dfs(int u, int p, bool keep){
    // process all light children
    for(int v : g[u]) if(v != p && v != heavy[u])
        dfs(v, u, false);

    // process heavy child (kept)
    if(heavy[u] != -1)
        dfs(heavy[u], u, true);

    // add light children contributions into current data
    for(int v : g[u]) if(v != p && v != heavy[u]){
        for(int t = tin[v]; t <= tout[v]; ++t){
            add_node(euler[t]);
        }
    }

    // add current node
    add_node(u);

    // compute answer for u
    int S = sz[u];
    int distinct_le_S = bit.sumPrefix(min(S, N)); // values are in [1..N]
    ans[u] = S - distinct_le_S;

    // if not keep, remove all nodes in this subtree
    if(!keep){
        for(int t = tin[u]; t <= tout[u]; ++t){
            remove_node(euler[t]);
        }
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int T;
    if(!(cin >> T)) return 0;
    while(T--){
        cin >> N;
        A.assign(N+1, 0);
        for(int i=1;i<=N;++i) cin >> A[i];

        g.assign(N+1, {});
        for(int i=0;i<N-1;++i){
            int u,v; cin >> u >> v;
            g[u].push_back(v);
            g[v].push_back(u);
        }

        sz.assign(N+1, 0);
        heavy.assign(N+1, -1);
        tin.assign(N+1, 0);
        tout.assign(N+1, 0);
        euler.assign(N+1, 0);
        timerdfs = 0;

        dfs_sz(1, 0);

        cnt.assign(N+1, 0);
        bit.init(N);
        ans.assign(N+1, 0);

        dfs(1, 0, true);

        int Q; cin >> Q;
        vector<int> queries(Q);
        for(int i=0;i<Q;++i) cin >> queries[i];

        for(int i=0;i<Q;++i){
            cout << ans[queries[i]] << (i+1==Q?'\n':'\n');
        }
    }
    return 0;
}

Information

Submit By
Type
Submission
Problem
P1157 H. Roy and Tree Permutation
Language
C++17 (G++ 13.2.0)
Submit At
2025-08-25 22:35:50
Judged At
2025-08-25 22:35:50
Judged By
Score
100
Total Time
72ms
Peak Memory
20.938 MiB