Submission #1139812

#TimeUsernameProblemLanguageResultExecution timeMemory
1139812LCJLYTourism (JOI23_tourism)C++20
100 / 100
364 ms27900 KiB
#include <bits/stdc++.h>
using namespace std;
 
#define int long long 
#define ld long double
#define show(x,y) cout << y << " " << #x << endl;
#define show2(x,y,i,j) cout << y << " " << #x << "  " << j << " " << #i << endl;
#define show3(x,y,i,j,p,q) cout << y << " " << #x << "  " << j << " " << #i << "  " << q << " " << #p << endl;
#define show4(x,y) for(auto it:y) cout << it << " "; cout << #x << endl;
typedef pair<int,int>pii;
typedef pair<pii,int>pi2;
mt19937_64 rng(chrono::system_clock::now().time_since_epoch().count());

vector<int>adj[100005];
int d[100005];
int sz[100005];

void dfs(int index, int par){
	if(adj[index].size()>1&&adj[index][0]==par) swap(adj[index][0],adj[index][1]);
	sz[index]=1;
	for(auto &it:adj[index]){
		if(it==par) continue;
		d[it]=d[index]+1;
		dfs(it,index);
		sz[index]+=sz[it];
		if(sz[it]>sz[adj[index][0]]) swap(it,adj[index][0]);
	}
}

int hp[100005];
int pp[100005];
int in[100005];
int out[100005];
int ptr=0;

void hld(int index, int par){
	in[index]=++ptr;
	for(auto it:adj[index]){
		if(it==par) continue;
		if(it==adj[index][0]) hp[it]=hp[index];
		else hp[it]=it;
		pp[it]=index;
		hld(it,index);
	}
	out[index]=ptr;
}

set<pi2>se[100005];

int fw[100005];

void upd(int x, int y){
	while(x<100005){
		fw[x]+=y;
		x+=x&(-x);
	}
}

int sum(int x){
	int counter=0;
	while(x>0){
		counter+=fw[x];
		x-=x&(-x);
	}
	return counter;
}

int query(int x, int y){
	return sum(y)-sum(x-1);
}

void add(int l, int r, int c, int index){
	//interval set
	//cout << l << " " << r << " " << c << " " << index << " add" << endl;
	//for(auto it:se[index]){
		//cout << it.first.second << " " << it.first.first << " " << it.second << " se\n";
	//}
	while(1){ 
		auto it=se[index].lower_bound({{l,0},0});
		if(it==se[index].end()) break;
		pi2 hold=*it;
		int lft=hold.first.second;
		int rgt=hold.first.first;
		if(lft>r) break;
		se[index].erase(se[index].find(hold));
		upd(hold.second,-(rgt-lft+1));
		if(lft<l){
			se[index].insert({{l-1,lft},hold.second});
			upd(hold.second,((l-1)-lft+1));
		}
		if(rgt>r){
			se[index].insert({{rgt,r+1},hold.second});
			upd(hold.second,(rgt-(r+1)+1));
		}
	}
	se[index].insert({{r,l},c});
	upd(c,r-l+1);
}

void solve(){
	int n,m,q;
	cin >> n >> m >> q;
	
	int temp,temp2;
	for(int x=0;x<n-1;x++){
		cin >> temp >> temp2;
		adj[temp].push_back(temp2);
		adj[temp2].push_back(temp);
	}
	
	dfs(1,-1);
	hp[1]=1;
	hld(1,-1);
	
	int take[m+5];
	for(int x=1;x<=m;x++){
		cin >> take[x];
	}
	
	vector<pii>storage[m+5];
	int ans[q];
	
	for(int x=0;x<q;x++){
		cin >> temp >> temp2;
		storage[temp2].push_back({temp,x});
	}
	
	//for(int x=1;x<=n;x++){
		//cout << hp[x] << " ";
	//}
	//cout << "\n";
	
	for(int x=1;x<=m;x++){
		if(x>1){
			//path
			int prev=take[x-1];
			int cur=take[x];
			while(hp[prev]!=hp[cur]){
				if(d[hp[prev]]>d[hp[cur]]) swap(prev,cur);
				//cur is deeper
				add(in[hp[cur]],in[cur],x-1,hp[cur]);
				cur=pp[hp[cur]];
				//for(int y=1;y<=x;y++){
					//cout << query(y,y) << " ";
				//}
				//cout << "before" << endl;
			}
			if(in[cur]>=in[prev]) swap(cur,prev);
			add(in[cur],in[prev],x-1,hp[cur]);
		}
		//for(int y=1;y<=x;y++){
			//cout << query(y,y) << " ";
		//}
		//cout << "before" << endl;
		add(in[take[x]],in[take[x]],x,hp[take[x]]);
		for(auto it:storage[x]){
			ans[it.second]=query(it.first,x);
		}
		//show(x,x);
		//for(int y=1;y<=x;y++){
			//cout << query(y,y) << " ";
		//}
		//cout << " fw" << endl;
	}
	
	for(int x=0;x<q;x++) cout << ans[x] << "\n";
}
 
int32_t main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	//freopen("in.txt","r",stdin);
	//freopen("in.txt","w",stdout);
	int t=1;	
	//cin >> t;	
	while(t--){
		solve(); 
	}
}
#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...