because they look like a couple leaning on each other. They share a same root, and their branches are intertwined. In China, many lovers go to the couple trees. Under the trees, lovers wish to be accompanied by a lifetime.
Ada and her boyfriend Asa came to the couple trees as well. They were very interested in the trees. They were all ACMers, so after careful observation, they found out that these two trees could be considered as two "trees" in graph theory. These two trees shared N vertices which were labeled 1 to N, and they all had exactly N vertices. Vertices 1 was the root of both trees.
Ada and Asa wanted to know more about the trees' rough bark, so each of them put one thumb at a vertices. Then they moved their thumbs towards the root. Ada moved along the wife tree, and Asa moved along the husband tree. Of course, they could moved at different speed.
At that moment, a thought suddenly came to Ada's mind: their thumbs may meet before the root. Which one was the earliest possible meeting vertex? And how many vertices would Ada and Asa encounter on the way to the meeting vertex?
The input consists of no more than 8 test cases.
For each test case:
The first line contains two integers, N and M, indicating the number of vertices and the number of queries.(1≤N,M≤100,000)
The next line contains N−1 integers. It describes the structure of wife tree in this way: If the ith integer is k, it means that the vertex labeled k is the father vertex of the vertex labeled (i+1) . It's guaranteed that a vertex X's father vertex can't have a larger label than X does.
The next line describes the husband tree in the same way.
Then next M lines describe the queries. Each line contains two integers Xi and Yi. Let Ki be the earliest possible meeting vertex of the ith query (K0 is defined as 0). In the ith query, Ada's thumb was put at the vertex labeled (Xi+Ki−1) mod N+1 and Asa's thumb was put at the vertex labeled (Yi+Ki−1) modN+1.(1≤Xi,Yi≤N) at the beginning.
For each test case:
Output the answer for each query in a single line. The answer contains three integers: the earliest possible meeting vertex, the number of the vertices Ada will encounter and the number of the vertices Asa will encounter (including the starting vertex and the ending vertex). In particular, if they put their thumb at the same vertex at first, the earliest possible meeting vertex should be the starting vertex.
5 1 1 2 3 3 1 1 3 2 4 3 5 3 1 1 2 2 1 2 2 1 5 3 5 4 3 5 5 3 1 1 2 2 1 2 3 1 1 4 1 1 3 4
3 2 2 1 1 3 1 2 1 2 2 1 1 2 2 3 1 1 2 1 2
In the first test case:
The wife tree is like this:
The husband tree is like this:
The query is (5)[4], and they may meet at {1,3}, so the earliest one is 3.
In the second test case:
The wife tree is like this:
The husband tree is like this:
The first query is (1)[4], the second query is (2)[1], and the last one is (5)[2].
For the first query, they may only meet at 1.
For the second query, they may only meet at 1.
For the third query, they may meet at {1,2}, the earliest one is 2.
题意很烦。。就是说两棵树,公用所有点,但是不公用边,每次询问给你两棵树起点,求最早的往根走相同的点和步数,输出这个点和步数。
由于题目保证了父节点都是比子节点的序号小,那么就有了单调性,那么就可以倍增了
也挺好写的
#include <bits/stdc++.h>
using namespace std;
const int N = 100100;
vector<int> e[N],e1[N];
int vis[N];
int f[N][20];
int f1[N][20];
void dfs(int u,int v)
{
for(int i=0;i<e[u].size();i++)
{
if(e[u][i]==v) continue;
f[e[u][i]][0]=u;
dfs(e[u][i],u);
}
}
void dfs2(int u,int v)
{
for(int i=0;i<e1[u].size();i++)
{
if(e1[u][i]==v) continue;
f1[e1[u][i]][0]=u;
dfs2(e1[u][i],u);
}
}
int n,m;
void ST()
{
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;i<=n;i++)
{
if(f[i][j-1]!=-1)
{
f[i][j]=f[f[i][j-1]][j-1];
}
if(f1[i][j-1]!=-1)
{
f1[i][j]=f1[f1[i][j-1]][j-1];
}
}
}
}
int solve(int x,int y)
{
int step=1,step2=1;
while(x!=y)
{
if(x<y)
{
for(int i=0;i<16;i++)
if(x<f1[y][i]&&f1[y][i]!=-1)
y=f1[y][i],step2+=(1<<i);
step2+=1,y=f1[y][0];
}
else {
for(int i=0;i<16;i++)
{
if(f[x][i]>y&&f[x][i]!=-1)
x=f[x][i],step+=(1<<i);
}
step+=1,x=f[x][0];
}
}
printf("%d %d %d\n",x,step,step2 );
return x;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(f,-1,sizeof(f));
memset(f1,-1,sizeof(f1));
for(int i=1;i<=n;i++)
e[i].clear(),e1[i].clear();
for(int i=2;i<=n;i++)
{
int d;
scanf("%d",&d);
e[d].push_back(i);
}
for(int i=2;i<=n;i++)
{
int d;
scanf("%d",&d);
e1[d].push_back(i);
}
dfs(1,0);
dfs2(1,0);
ST();
int k;
k=0;
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
u=(u+k)%n+1;
v=(v+k)%n+1;
k=solve(u,v);
}
}
}