Submission #1216404

#TimeUsernameProblemLanguageResultExecution timeMemory
1216404kiteyuRegions (IOI09_regions)C++20
70 / 100
8076 ms33628 KiB
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 2e5 + 5;
const int R = 25005;
const int S = 30000;
int n, r, q, in[N], out[N], T = 0;
vector<int> g[N], reg[R];
map<pair<int,int>,int> mp;
vector<int> Spe;
int bit[N];

void dfs(int x,int p = 0){
    in[x] = ++T;
    for(int j : g[x]) if(j != p){
        dfs(j,x);
    }
    out[x] = T;
}

void upd(int idx,int val){
    for(;idx <= T ; idx += (idx & (-idx))) bit[idx] += val;
}

int get(int idx){
    ll s = 0;
    for(;idx ;idx -= (idx & (-idx))) s += bit[idx];
    return s;
}

int main(){
    ios::sync_with_stdio(0);cin.tie(0);
    cin >> n >> r >> q;
    int x,y; cin >> x; reg[x].push_back(1);
    for(int i = 2 ; i <= n ; ++i){
        cin >> x >> y;
        g[x].push_back(i);
        reg[y].push_back(i);
    }
    dfs(1);
    for(int i = 1 ; i <= r ; ++i)
        if((int)reg[i].size() >= S) Spe.push_back(i);
    for(int i : Spe){

        for(int l : reg[i]) {
            upd(in[l],1);
            upd(out[l] + 1,-1);
        }

        for(int j = 1 ; j <= n ; ++j){
            int ans = 0;
            for(int l : reg[j]) ans += get(in[l]) - (i == j);
            mp[{i,j}] = ans;
        }

        for(int l : reg[i]) upd(out[l] + 1,1);

        for(int j = 1 ; j <= n ; ++j){
            int ans = 0;
            for(int l : reg[j]) ans += get(out[l]) - get(in[l]) - (i == j);
            mp[{j,i}] = ans;
        }

        for(int l : reg[i]) upd(in[l],-1);
    }
    int u, v;
    while(q--){
        cin >> u >> v;
        if(mp.count({u,v})) {cout << mp[{u,v}]<< endl; continue;}
        //cout << "?\n";
        for(int j : reg[u]) {
            //cout << j << '.' << in[j] << ' ' << out[j] << '\n';
            upd(in[j],1);
            upd(out[j] + 1,-1);
        }
        //cout << "??\n";
        int ans = 0;
        for(int j : reg[v])
            ans += get(in[j]) - (u == v);
        //cout << "???\n";
        for(int j : reg[u]) upd(out[j] + 1,1);

        mp[{u,v}] = ans;
        cout << ans << endl;
        if(u != v){
            ans = 0;
            for(int j : reg[v]) ans += get(out[j]) - get(in[j]);
            mp[{v,u}] = ans;
        }
        for(int j : reg[u]) upd(in[j],-1);


    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...