제출 #1132046

#제출 시각아이디문제언어결과실행 시간메모리
1132046ByeWorldRegions (IOI09_regions)C++20
18 / 100
546 ms196608 KiB
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#define ll long long
#define pb push_back
#define fi first
#define se second
#define lf (id<<1)
#define rg ((id<<1)|1)
#define md ((l+r)>>1)
#define ld long double
using namespace std;
typedef pair<int,int> pii;
typedef pair<char,char> pcc;
typedef pair<int,pii> ipii;
typedef pair<pii,pii> ipiii;
const int MAXN = 2e5+10;
const int SQRT = 160;
const int MAXA = 160;
const int MOD = 1e9+7;
const int INF = 1e9+10;
const int LOG = 21;
const ld EPS = 1e-12;

int n, r, k, a[MAXN], siz;
vector <int> adj[MAXN], idx[MAXN], big;
int in[MAXN],out[MAXN],tim, par[MAXN], bigidx[MAXN];
int heavy[MAXA+10][MAXA+10], up[MAXN][MAXA+10], dw[MAXN][MAXA+10];

void dfs(int nw){
	in[nw] = ++tim;
	for(int i=0; i<siz; i++) up[nw][i] = up[par[nw]][i];
	if(bigidx[nw] != -1)
		up[nw][bigidx[ a[nw] ]]++, dw[nw][bigidx[ a[nw] ]]++;

	for(auto nx : adj[nw]){
		dfs(nx);
		for(int i=0; i<siz; i++)
			dw[nw][i] += dw[nx][i];
	}
	out[nw] = tim;
}
struct seg {
	int st[2*MAXN];
	int que(int x){
		int te = 0;
		for(; x>=1; x-=(x&(-x))) te += st[x];
		return te;
	}
	void upd(int x,int y){
		for(;x<=2*MAXN-20;x+=(x&(-x)))
			st[x] += y;
	}
} A;
signed main(){
    // ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n>>r>>k;
	cin >> a[1]; idx[a[1]].pb(1);
	for(int i=2; i<=n; i++){
		cin>>par[i]>>a[i]; adj[par[i]].pb(i);
		idx[a[i]].pb(i);
	}
	for(int i=1; i<=r; i++){
		if(idx[i].size() >= SQRT) bigidx[i]=big.size(), big.pb(i);
		else bigidx[i] = -1;
	}
	siz = big.size();
	dfs(1);
	for(int i=0; i<siz; i++){
		for(int j=0; j<siz; j++){
			// cout << big[i] << ' ' << big[j] << " p\n";
			for(auto id : idx[big[j]]){
				// cout << id << " pp\n";
				heavy[i][j] += up[id][i];
			}
		}
	}

	while(k--){
		int x, y; cin>>x>>y; // x di atas y
		int ans = 0;
		if(idx[x].size()<SQRT){
			if(idx[y].size()<SQRT){
				for(auto id : idx[y]) A.upd(in[id], 1);
				for(auto id : idx[x]) 
					ans += A.que(out[id])-A.que(in[id]-1);
				for(auto id : idx[y]) A.upd(in[id], -1);

			} else {
				for(auto id : idx[x])
					ans += dw[id][bigidx[ a[y] ]];
			} 
		} else {
			if(idx[y].size()<SQRT){ 
				for(auto id : idx[y])
					ans += up[id][bigidx[ a[x] ]];
			} else { // big-big
				// cout << "bigbig\n";
				ans = heavy[bigidx[x]][bigidx[y]];
			} 
		}
		cout << ans << endl;
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...