제출 #913919

#제출 시각아이디문제언어결과실행 시간메모리
913919VMaksimoski008Regions (IOI09_regions)C++14
30 / 100
1806 ms99232 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
 
const int maxn = 2e5 + 5;
 
void setIO() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}
 
int n, r, q, i, in[maxn], out[maxn], timer = 0, ans = 0;
short home[maxn], r1, r2;
vector<vector<int> > graph, dp;
 
void dfs(int u) {
    dp[home[u]][u]++;
 
    for(int &v : graph[u]) {
        dfs(v);
        for(i=1; i<=r; i++)
            dp[i][u] += dp[i][v];
    }
}

void dfs2(int u) {
    in[u] = timer++;
    for(int &v : graph[u])
        dfs(v);
    out[u] = timer;
}

bool anc(int u, int v) { return (in[u] <= in[v] && out[u] >= out[v]); }
 
int32_t main() {
    setIO();
 
    cin >> n >> r >> q;
    graph.resize(n+1);
    vector<int> cnt(r+1);
 
    cin >> home[1];
    cnt[home[1]]++;
 
    for(i=2; i<=n; i++) {
        int p;
        cin >> p >> home[i];
        cnt[home[i]]++;
        graph[p].push_back(i);
    }
 
    if(r <= 500) {
        dp.resize(r+1, vector<int>(n+1));
        dfs(1);
 
        vector<vector<int> > by_home(r+1);
        for(i=1; i<=n; i++)
            by_home[home[i]].push_back(i);
 
        while(q--) {
            ans = 0;
            cin >> r1 >> r2;
 
            for(int &x : by_home[r1])
                ans += dp[r2][x];
        
            cout << ans << endl;
        }
        return 0;
    }

    if(*max_element(cnt.begin(), cnt.end()) <= 500) {
        dfs2(1);

        vector<vector<int> > by_home(r+1);
        for(i=1; i<=n; i++)
            by_home[home[i]].push_back(i);

        while(q--) {
            ans = 0;
            cin >> r1 >> r2;

            for(int &u : by_home[r1])
                for(int &v : by_home[r2]) ans += anc(u, v);

            cout << ans << endl;
        }
    }
 
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...