제출 #889635

#제출 시각아이디문제언어결과실행 시간메모리
889635vjudge1Tourism (JOI23_tourism)C++17
35 / 100
5076 ms50716 KiB
#include <bits/stdc++.h>
using namespace std;

#define ff first
#define ss second
#define all(a) a.begin(), a.end()
const int mod = 998244353;
const int N = 1e5;


pair<int, int> chmax(pair<int, int> A, pair<int, int> B){
	if(A.ff > B.ff) return A;
	return B;
}

pair<int, int> chmin(pair<int, int> A, pair<int, int> B){
	if(A.ff > B.ff) return B;
	return A;
}

struct sparse{
	vector<vector<pair<int, int> > > m_table;
	vector<vector<pair<int, int> > >  ma_table;
	int n;
	
	sparse(int sz){
		n = sz;
		m_table.resize(18);
		ma_table.resize(18);
		for(auto &i : m_table){
			i.resize(sz);
		} 
		for(auto &i : ma_table) i.resize(sz);
	};
	
	void build(vector<pair<int, int>> &a){
		for(int lg = 0; lg < 18; lg++){
			for(int i = 0;i < n; i++){
				if(lg == 0){
					m_table[lg][i] = a[i];
					ma_table[lg][i] = a[i];
				}else{
					int k = 1<<(lg-1);
					m_table[lg][i] = chmin(m_table[lg-1][i], m_table[lg-1][min(n - 1, i +  k)]);
					ma_table[lg][i] = chmax(ma_table[lg-1][i], ma_table[lg-1][min(n - 1, i +  k)]);
				}
			}
		}
	}
	
	pair<int, int> get_max(int l, int r){
		int k = __lg(r-l+1);
		return chmax(ma_table[k][l], ma_table[k][r-(1<<k) + 1]);
	}
	
	pair<int, int> get_min(int l, int r){
		int k = __lg(r-l+1);
		return chmin(m_table[k][l], m_table[k][r-(1<<k) + 1]);
	}
	
		
};





vector<int> g[N+1];
int depth[N+1], c[N+1];
int timer=1;
int tin[N+1], tout[N+1];
int up[N+1][18];
int n, m, q;

void dfs(int v, int par){
	up[v][0] = par;
	tin[v] = timer++;
	for(int i = 1;i < 18; i++){
		up[v][i] = up[up[v][i-1]][i-1];
	}
	for(int to : g[v]){
		if(to == par) continue;
		depth[to] = depth[v] + 1;
		dfs(to, v);
	}
	tout[v] = timer++;
}

int lca(int a, int b){
	if(depth[a] > depth[b]) swap(a, b);
	int k = depth[b] - depth[a];
	for(int i = 0;i < 18; i++){
		if(k & (1<<i)){
			b = up[b][i];
		}
	}
	if(a == b) return a;
	for(int i = 17; i >= 0; i--){
		if(up[a][i] != up[b][i]){
			a = up[a][i];
			b = up[b][i];
		}
	}
	return up[a][0];
}

int vert;
vector<int> vec;


int in_subtree(int v){
	int it = lower_bound(all(vec), tin[v]) - vec.begin();
	if(it < (int)vec.size() && vec[it] <= tout[v]) return 1;
	return 0;
}

void ans(int v, int par){
	if(!in_subtree(v)) return;
	vert++;
	for(int to : g[v]){
		if(to == par) continue;
		ans(to, v);
	}
}





signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	 cin >> n >> m >> q;
	 int bambo = 1;
	for(int i = 1;i < n; i++){
		int a, b; cin >> a >> b;
		if(a != i || b != a+1) bambo = 0;
		g[a].push_back(b);
		g[b].push_back(a);
	}
	for(int i = 0;i < m; i++){
		cin >> c[i];
	}
	dfs(1, 1);
	vector<pair<int, int> > vals;
	for(int i = 0;i < m; i++){
		vals.push_back(make_pair(tin[c[i]], c[i]));
	}
	sparse table(m);
	table.build(vals);
	if(bambo){
		
		while(q--){
			int l, r; cin >> l >> r;
			l--, r--;
			int mn = table.get_min(l, r).ss;
			int mx = table.get_max(l, r).ss;
			cout << depth[mx] - depth[mn]  + 1 << '\n';
			
		}
		
		return 0;
	}
	while(q--){
		int l, r; cin >> l >> r;
		l--, r--;
		int mn = c[l], mx = c[l];
		vec.clear();
		for(int i = l;i <= r; i++){
			vec.push_back(tin[c[i]]);
			if(tin[mn] > tin[c[i]]){
				mn = c[i];
			}
			if(tin[mx] < tin[c[i]]){
				mx = c[i];
			}
		}
		
		mn = table.get_min(l, r).ss;
		mx = table.get_max(l, r).ss;
		sort(all(vec));
		vec.erase(unique(all(vec)), vec.end());
		vert = 0;
		int lc = lca(mn, mx);
		ans(lc, up[lc][0]);
		
		cout << vert << '\n';
		
	}
	
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...