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);
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值