题意:给出一棵无向的树(n<=1e6),开始树的所有vertex都是白色的,然后给出q(<=1e6)次询问,询问分为1、2两种:1:将index号节点涂成黑色。2:询问index号节点到所有的小黑点的简单路径中的标号最小的那个点(包括起点和小黑点)。题目保证第一次询问是1类型的。
题解:如果我们随便选取root,那么询问的时候,我们要找到这个点到所有小黑点的路径(LCA),但是这样显然会超时的。所以我们换一种建树姿势。由于第一个询问必然是1类型,那么我们就把第一次询问的那个变黑的点作为root,看一下这样有什么好处:假设我们树上已经有了一些小黑点了,那么当我们遇到2类型询问index的时候,我们考虑index到所有的小黑点的简单路径:首先是root,路径就是index到根,其次考虑非root的小黑点,分成两种情况:1、lca(小黑点,index)==root,那么index到这个小黑点的简单路径是index-root-小黑点。2、lca(index,小黑点)!=root,那么index到小黑点的路径是index-lca-小黑点,而lca必然在index-root的路径上。而因为root是小黑点,所以index-root上的最小值一定会被考虑,而lca-root必然是index-root的一段,所以说index-lca-小黑点这条路可以拆成index-root和root-小黑点。(因为lca-root这条路径必然会被考虑,所以可以把index-lca-小黑点的检测范围拓展一下,对答案毫无影响)。因此我们只需要记录下树上每个vertex到root的路径上所有点标号最小的那一个(先求Deep,然后跑DFS),之后就可以O(1)出答案了。
注意:1、本题强制在线,需要记录last=最后一次2询问的ans,并且每次询问的点的index=(input+last)%n+1。
2、cin、cout慢的出翔,解绑流之后效率依然不足够,乖乖的用scanf/printf吧。
Code:
#include<bits/stdc++.h>
using namespace std;
#define MAX 1000006
#define INF n+1
int n,q;
vector<int> E[MAX];
int minNum[MAX];
int que[MAX*5];
int deep[MAX];
int root;
int last = 0;
int ans ;
void init(){
cin>>n>>q;
for (int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
E[u].push_back(v);
E[v].push_back(u);
}
scanf("%d%d",&root,&root);
root = root%n+1;
ans = root;
q--;
for (int i=0;i<=n;i++){
minNum[i] = i;
}
}
void initBuild(){
int l =0,r=1;
que[1] = root;
deep[root] = 1;
while (l<r){
l++;
int a = que[l];
for (vector<int>::iterator it = E[a].begin();it!=E[a].end();it++){
if (deep[(*it)]==0){
deep[(*it)] = deep[a]+1;
r++;
que[r] = (*it);
}
}
}
}
void build (){
initBuild();
int l=0,r=1;
que[1]=root;
minNum[root] = root;
while (l<r){
l++;
int a = que[l];
int temp = minNum[a];
for (vector<int>::iterator it = E[a].begin();it!=E[a].end();it++){
if (deep[(*it)]>deep[a]){
minNum[(*it)] = min(temp,minNum[(*it)]);
r++;
que[r] = (*it);
}
}
}
}
void solve(){
while (q--){
int flag,index;
scanf("%d%d",&flag,&index);
index = (index+last)%n+1;
if (flag==1){
ans = min (ans,minNum[index]);
}else{
last = min(ans,minNum[index]);
printf("%d\n",last);
}
}
}
int main(){
init();
build();
solve();
return 0;
}