2015北京网络赛 F Couple Trees 暴力倍增

Couple Trees

Time Limit: 1 Sec  

Memory Limit: 256 MB

题目连接

http://hihocoder.com/problemset/problem/1232

Description

"Couple Trees" are two trees, a husband tree and a wife tree. They are named 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?

Input

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) mod N + 1.(1≤Xi,Yi≤N) at the beginning.

Output

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.

Sample Input

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

Sample Output

3 2 2
1 1 3
1 2 1
2 2 1
1 2 2
3 1 1
2 1 2

HINT

 

题意

给你两棵树,都同时往上爬,问你这两个人都能够经过的点中,最大的点是什么,并且都各走了多少步

题解:

倍增就好了,直接暴力往上爬

然而并没有什么算法难度= =

当然这个做法是水过去的,并不是正解

代码:

//qscqesze
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <bitset>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 100006
#define mod 1000000007
#define eps 1e-9
#define PI acos(-1)
const double EP  = 1E-10 ;
int Num;
//const int inf=0x7fffffff;
const ll inf=999999999;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
//*************************************************************************************
int fa[maxn][20],fb[maxn][20],deepa[maxn],deepb[maxn];
int n,m;
int x,y;
int stepx,stepy,lastans;
void solve(int x,int y)
{
    while(x!=y)
    {
        if(x<y)
        {
            for(int i=15;i>=0;i--)
                if(fb[y][i]>x)y=fb[y][i],stepy+=1<<i;
            y=fb[y][0];stepy++;
        }
        else
        {
            for(int i=15;i>=0;i--)
                if(fa[x][i]>y)x=fa[x][i],stepx+=1<<i;
            x=fa[x][0];stepx++;
        }
    }
    lastans = x;
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=0;i<=15;i++)
            fa[1][i]=fb[1][i]=1;
        deepa[1]=deepb[1]=1;
        for(int i=2;i<=n;i++)
        {
            fa[i][0]=read();
            deepa[i]=deepa[fa[i][0]]+1;
            for(int j=1;j<=15;j++)
                fa[i][j]=fa[fa[i][j-1]][j-1];
        }
        for(int i=2;i<=n;i++)
        {
            fb[i][0]=read();
            deepb[i]=deepb[fb[i][0]]+1;
            for(int j=1;j<=15;j++)
                fb[i][j]=fb[fb[i][j-1]][j-1];
        }
        lastans = 0;
        while(m--)
        {
            x=read(),y=read();
            x = (x+lastans)%n+1;
            y = (y+lastans)%n+1;
            stepx=stepy=1;
            solve(x,y);
            printf("%d %d %d\n",lastans,stepx,stepy);
        }
    }
}

 

posted @ 2015-09-21 19:09  qscqesze  阅读(1244)  评论(4编辑  收藏  举报