結果

問題 No.3189 Semifinal Stage
ユーザー 沙耶花
提出日時 2025-06-20 22:04:43
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 2,439 ms / 4,000 ms
コード長 2,725 bytes
コンパイル時間 3,790 ms
コンパイル使用メモリ 260,856 KB
実行使用メモリ 21,540 KB
最終ジャッジ日時 2025-07-03 15:40:29
合計ジャッジ時間 48,754 ms
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 30
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <stdio.h>
#include <atcoder/all>
#include <bits/stdc++.h>
using namespace std;
using namespace atcoder;
using mint = modint;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define Inf32 1000000005
#define Inf64 4000000000000000001LL
struct lca{
	
	vector<int> depth;
	vector<vector<int>> parents;
	
	int max_j=18;
	
	lca(int n,vector<vector<int>> &E){
		rep(i,100){
			if((1<<i)>E.size()){
				max_j = i;
				break;
			}
		}
		depth.assign(E.size(),-1);
		parents.assign(E.size(),vector<int>(max_j,-1));
		
		
		
		stack<int> s;
		s.push(n);
		depth[n] = 0;
		while(s.size()!=0){
			int k = s.top();
			s.pop();
			for(int i=0;i<E[k].size();i++){
				int x = E[k][i];
				if(depth[x]!=-1)continue;
				s.push(x);
				depth[x] = depth[k]+1;
				for(int j=0;j<max_j;j++){
					if(j==0){
						parents[x][j] = k;
					}
					else{
						parents[x][j] = parents[parents[x][j-1]][j-1];
					}
					if(parents[x][j] == -1)break;
				}
			}
		}
	}
	
	
	int kth_parent(int u,int k){
		for(int i=0;i<max_j;i++){
			if(k==0)break;
			if(u==-1)break;
			if(k%2){
				u = parents[u][i];
			}
			k/=2;
		}
		return u;
	}
	
	int query(int u,int v){
		if(depth[u]<depth[v])swap(u,v);
		u = kth_parent(u,depth[u]-depth[v]);
		
		if(u==v){
			return u;
		}
		
		for(int i=max_j-1;i>=0;i--){
			if(parents[u][i]!=parents[v][i]){
				u = parents[u][i];
				v = parents[v][i];
			}
		}
		
		return parents[u][0];
		
	}
	
	int get_distance(int u,int v){
		return depth[u]+depth[v]-2*depth[query(u,v)];
	}
	
	
};
int main(){
	
	int n;
	cin>>n;
	
	vector<vector<int>> E(n);
	rep(i,n-1){
		int u,v;
		cin>>u>>v;
		u--,v--;
		E[u].push_back(v);
		E[v].push_back(u);
	}
	lca L(0,E);
	int q;
	cin>>q;
	vector<int> t(q),v(q);
	rep(i,q){
		cin>>t[i]>>v[i];
		v[i]--;
	}
	int B = 300;
	for(int i=0;i<q;i+=B){
		vector<int> f(n);
		for(int j=0;j<i;j++){
			if(t[j]==1)f[v[j]]^=1;
		}
		vector ok = f;
		for(int j=i;j<min(i+B,q);j++){
			if(t[j]==1)ok[v[j]] = 0;
		}
		vector<int> dis(n,Inf32);
		queue<int> Q;
		rep(j,n){
			if(ok[j]){
				Q.push(j);
				dis[j] = 0;
			}
		}
		while(Q.size()>0){
			int u = Q.front();
			Q.pop();
			for(int v : E[u]){
				if(dis[v] > dis[u] + 1){
					dis[v] = dis[u] + 1;
					Q.push(v);
				}
			}
		}
		vector<int> checks;
		rep(j,n){
			if(f[j] && !ok[j])checks.push_back(j);
		}
		for(int j=i;j<min(i+B,q);j++){
			if(t[j]==1){
				if(f[v[j]]){
					f[v[j]] = 0;
					auto it = find(checks.begin(), checks.end(), v[j]);
					if(it != checks.end()) checks.erase(it);
				}
				else{
					f[v[j]] = 1;
					checks.push_back(v[j]);
				}
			}
			else{
				int ans = dis[v[j]];
				rep(k,checks.size()){
					ans = min(ans,L.get_distance(checks[k],v[j]));
				}
				cout<<ans<<endl;
			}
			
		}
	}
	return 0;
}
0