HLG 1373 Leyni, LOLI and Leaders【括号定理】

Description

Professor Leyni likes to play with LOLIs and he has a lot of LOLIs to manage.

For easy management, Leyni numbered them from 1 to n, then arranged some leading relationships between them, such as, x leads y.

This relationship is transitive (i.e. if x is the leader of y, y leads z, and then x will lead z.).Leyni ensures that the arrangements will not conflict (i.e. x will not lead x by itself, x will not lead y if y leads x).

Since there are too many LOLIs, it troubles him whenever he would like to know the relationship between some pairs of LOLIs, please help him!

Input

There are multiple test cases. The first line of input is an integer T indicating the number of test cases. Then T test cases follow.

For each test case:

Line 1. This line contains a single integer n (2 ≤ n ≤ 105) indicating the number of LOLIs.

Line 2. This line contains n integers l1l2ln (0 ≤ lin) separated by a single space. It means the leader of i is li. It means i is headed by Leyni when li = 0.

Line 3. This line contains an integer Q (1 ≤ Q ≤ 105) indicating the number of queries about the relationship of some pairs of LOLIs.

Line 4..3 + Q. Each line contains two integer x and y (1 ≤ xyn)indicating two different LOLIs of each query.

Output

For each test case:

Line 1..Q. Corresponding to each query, an answer per line. Output "x>y" if x leads y, output "x<y" if y leads x, otherwise output "x<>y" instead.

Sample Input

1

10

2 3 6 3 1 0 3 6 6 6

5

10 5

9 10

3 5

8 2

5 1

Sample Output

10<>5

9<>10

3>5

8<>2

5<1

分析:

根据题意,判断一颗树中,某个点是否是另一个点的后裔。根据递归函数的入栈出栈时间戳特点(即子结点的入栈时间戳要晚于自己,而且子节点的出栈时间戳要早于自己)或者括号定理在O(N)内预处理一遍图,即可在O(1)时间完成每次查询。

d[x]表示深度优先搜索中x的访问时间戳

f[x]表示深度优先搜索中x的结束访问时间戳

如果d[u] < d[v] < f[v] < f[u],那么vu的后裔。

 

总结: 继续刷题吧。。

View Code
#include<stdio.h>
#include<string.h>
int f[100005],d[100005];
struct node
{
    int to,next;
}q[1000000];
int head[100005];
int tot;
int ti;
void add(int s,int u)
{
    q[tot].to=u;
    q[tot].next=head[s];
    head[s]=tot++;
}
void dfs(int r)
{
    int k,i,flag=1;
    d[r]=ti++;
    for(i=head[r];i;i=q[i].next)
    {
        flag=0;
        k=q[i].to;
        dfs(k);
    }
    f[r]=ti++;
}
int main()
{
    int t,n,i,p,root,a,b,Q;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        memset(head,0,sizeof(head));
        tot=1;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&p);
            if(p==0)
                root=i;
            else
                add(p,i);
        }
        memset(d,0,sizeof(d));
        memset(f,0,sizeof(f));
        ti=0;
        dfs(root);
        scanf("%d",&Q);
        while(Q--)
        {
            scanf("%d%d",&a,&b);
            if(d[a]<d[b]&&d[b]<=f[b]&&f[b]<=f[a])
                printf("%d>%d\n",a,b);
            else if(d[b]<d[a]&&d[a]<=f[a]&&f[a]<=f[b])
                printf("%d<%d\n",a,b);
            else printf("%d<>%d\n",a,b);
        }
    }
    return 0;
}

 

 

posted @ 2012-04-23 12:55  'wind  阅读(229)  评论(0编辑  收藏  举报