Submission #1369489

#TimeUsernameProblemLanguageResultExecution timeMemory
1369489greedyajRegions (IOI09_regions)C++20
15 / 100
5244 ms196608 KiB
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<algorithm>
#include<cmath>
#include<climits>
#include<string>
#include<numeric>
#include<deque>
using namespace std;

// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;

// #define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>

#define int long long
#define vi vector<int>
#define pii pair<int,int>
#define yes cout<<"YES\n"
#define no cout<<"NO\n"
#define all(x) x.begin(),x.end()
#define ull unsigned long long
#define vs vector<string>

const int INF = 1e18;
const int modx = 1e9 + 7;
const int maxn = 2e5 + 1;

vector<vector<int>> g;
vector<int> tin;
vector<int> tout;
vector<int> col;


void dfs(int cur, int par, int &timer){
   tin[cur] = timer++;

   for(auto &x : g[cur]){
   	if(x != par) dfs(x,cur,timer);
   }

   tout[cur] = timer++;
}

void dfs2(int cur, int par, int region, map<pair<int,int>,int> &ans, int cnt){
	if(col[cur] == region) cnt++;
	else{
		ans[{region,col[cur]}] += cnt;
	}

	for(auto &x : g[cur]){
   	if(x != par) dfs2(x,cur,region,ans,cnt);
   }
}

void solve(){
  	int n,r,q; cin >> n >> r >> q;

  	g.resize(n);
  	tin.resize(n);
  	tout.resize(n);
  	col.resize(n);

  	vector<pair<int,int>> rtin[r];

    cin >> col[0]; col[0]--;

    for(int i = 0; i < n - 1; i++){
    	int s,h; cin >> s >> h; s--; h--; 
    	col[i+1] = h;
    	g[i+1].push_back(s);
    	g[s].push_back(i+1);
    }
    
    int timer = 0;
    dfs(0,-1,timer);

    for(int i = 0; i < n; i++){
    	rtin[col[i]].push_back({tin[i],tout[i]});
    }

    for(int i = 0; i < r; i++){
    	sort(all(rtin[i]));
    }

    map<pair<int,int>,int> ans;

    for(int i = 0; i < r; i++){
    	if(rtin[i].size() <= 500){
           dfs2(0,-1,i,ans,0);
    	}
    }

    while(q--){
    	int r1, r2; cin >> r1 >> r2; r1--; r2--;
    	if(rtin[r1].size() <= 500){
    		int total_count = 0;
            for(auto &[xin,xout] : rtin[r1]){
              // Check how many nodes exist with tin greater than xin and tout less than xout
              total_count += upper_bound(all(rtin[r2]), make_pair(xout,INF))  - upper_bound(all(rtin[r2]), make_pair(xin,INF));
            }
            cout << total_count << endl;
    	} else{
    		cout << ans[{r1,r2}] << endl;
    	}
    }


}

int32_t main(){
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    // #ifndef ONLINE_JUDGE
    // freopen("input.txt","r",stdin);
    // freopen("output.txt","w",stdout);
    // freopen("error.txt","w",stderr);
    // #endif

    int t = 1;

    while(t--){
      solve();
    }
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...