Submission #1139756

#TimeUsernameProblemLanguageResultExecution timeMemory
1139756LCJLYTourism (JOI23_tourism)C++20
28 / 100
5092 ms29136 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<int,pii>pi2;
mt19937_64 rng(chrono::system_clock::now().time_since_epoch().count());

vector<int>adj[100005];
int in[100005];
int out[100005];
int two[22][100005];
int d[100005];
int ptr=0;

void dfs(int index, int par){
	in[index]=++ptr;
	for(int x=0;x<18;x++){
		two[x+1][index]=two[x][two[x][index]];
	}
	for(auto it:adj[index]){
		if(it==par) continue;
		two[0][it]=index;
		d[it]=d[index]+1;
		dfs(it,index);
	}
	out[index]=ptr;
}

int lca(int a, int b){
	if(d[a]>d[b]) swap(a,b);
	int diff=d[b]-d[a];
	for(int x=0;x<18;x++){
		if(diff&(1<<x)){
			b=two[x][b];
		}
	}
	if(a==b) return a;
	for(int x=18;x>=0;x--){
		if(two[x][a]!=two[x][b]){
			a=two[x][a];
			b=two[x][b];
		}
	}
	return two[0][a];
}

int f(int a, int b){
	return d[a]+d[b]-2*d[lca(a,b)];
}

int counter=0;
multiset<pii>se;

void add(int x){
	auto nxt=se.upper_bound({in[x],x});
	auto prev=se.lower_bound({in[x],x});
	
	if(nxt==se.end()&&prev==se.begin()){
	}
	else if(nxt==se.end()){
		prev--;
		pii hold=*prev;
		counter+=f(hold.second,x);
	}
	else if(prev==se.begin()){
		pii hold=*nxt;
		counter+=f(hold.second,x);
	}
	else{
		prev--;
		pii hold=*prev;
		pii hold2=*nxt;
		counter-=f(hold.second,hold2.second);
		counter+=f(hold.second,x);
		counter+=f(hold2.second,x);
	}
	
	se.insert({in[x],x});
}

void dlt(int l){
	auto nxt=se.upper_bound({in[l],l});
	auto prv=prev(nxt);
	
	if(nxt==se.end()&&prv==se.begin()){
	}
	else if(nxt==se.end()){
		prv--;
		pii hold=*prv;
		counter-=f(hold.second,l);
	}
	else if(prv==se.begin()){
		pii hold=*nxt;
		counter-=f(hold.second,l);
	}
	else{
		prv--;
		pii hold=*prv;
		pii hold2=*nxt;
		counter+=f(hold.second,hold2.second);
		counter-=f(hold.second,l);
		counter-=f(hold2.second,l);
	}
	
	se.erase(se.find({in[l],l}));
}

int blk=300;
bool cmp(const pair<pii,int>a, const pair<pii,int>b){
	int blka=a.first.first/blk;
	int blkb=b.first.first/blk;
	if(blka==blkb) return a.first.second < b.first.second;
	return blka < blkb;
}

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);
	
	int l=1;
	int r=1;
	
	int take[m+5];
	for(int x=1;x<=m;x++) cin >> take[x];
	
	pair<pii,int>que[q];
	for(int x=0;x<q;x++){
		cin >> que[x].first.first >> que[x].first.second;
		que[x].second=x;
	}
	
	add(take[1]);
	
	sort(que,que+q,cmp);
	
	int ans[q];
	int cnt[n+5];
	memset(cnt,0,sizeof(cnt));
	cnt[take[1]]++;
	for(int x=0;x<q;x++){
		int lft=que[x].first.first;
		int rgt=que[x].first.second;
		int index=que[x].second;
		
		while(l>lft){
			l--;
			cnt[take[l]]++;
			if(cnt[take[l]]==1)add(take[l]);
		}
		while(r<rgt){
			r++;
			cnt[take[r]]++;
			if(cnt[take[r]]==1)add(take[r]);
		}
		while(l<lft){
			cnt[take[l]]--;
			if(cnt[take[l]]==0)dlt(take[l]);			
			l++;
		}
		while(r>rgt){
			cnt[take[r]]--;
			if(cnt[take[r]]==0)dlt(take[r]);
			r--;
		}
		//show2(lft,lft,rgt,rgt);
		//for(auto it:se) cout << it.second << " ";
		//cout << "\n";
		
		ans[index]=(counter+f(se.begin()->second,prev(se.end())->second))/2+1;
		//show(counter,ans[index]);
	}
	
	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...