bestcoders pog love szhIII

pog loves szh III

Accepts: 63

Submissions: 483

Time Limit: 12000/6000 MS (Java/Others)

Memory Limit: 131072/131072 K (Java/Others)

问题描述

pog在与szh玩游戏,首先pog在纸上画了一棵有根树,这里我们定义1为这棵树的根,然后szh在这棵树中选了若干个点,想让pog帮忙找找这些点的最近公共祖先在哪里,一个点为S的最近公共祖先当且仅当以该点为根的子树包含S中的所有点,且该点深度最大。然而,这个问题是十分困难的,出于szh对pog的爱,他决定只找编号连续的点,即li~ri。

输入描述

若干组数据(不超过3组n≥10000或Q≥10000)。
每组数据第一行一个整数n(1≤n≤300000),表示树的节点个数。
接下来n?1行,每行两个数Ai,Bi,表示存在一条边连接这两个节点。
接下来一行一个数Q(1≤Q≤300000),表示有Q组询问。
接下来Q行每行两个数li,ri(1≤li≤ri≤n),表示询问编号为li~ri的点的最近公共祖先。

输出描述

对于每组的每个询问,输出一行,表示编号为li~ri的点的最近公共祖先的编号。

输入样例

5
1 2
1 3
3 4
4 5
5
1 2
2 3
3 4
3 5
1 5

输出样例

1
1
3
3
1

Hint

珍爱生命,远离爆栈。
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 400000 + 10;
const int DEG = 20;

int n, lca[N<<2];

struct Edge
{
    int to, next;
}edge[N*2]; // Undirectional edge

int head[N], tot;

void init()
{
    tot = 0;
    memset(head, -1, sizeof(head));
}

void adde(int u, int v)
{
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}

int fa[N][DEG], deg[N];

void BFS(int root) //预处理得到之后二分搜索所需的顶点信息
{
    queue<int> que;
    deg[root] = 0;
    fa[root][0] = root;
    que.push(root);
    while(!que.empty())
    {
        int u = que.front();
        que.pop();

        for(int i=1; i<DEG; i++)
            fa[u][i] = fa[fa[u][i-1]][i-1];
        for(int i=head[u]; i!=-1; i=edge[i].next)
        {
            int v = edge[i].to;
            if(v == fa[u][0]) continue; //判断该节点之前是否访问过
            deg[v] = deg[u] + 1;
            fa[v][0] = u;
            que.push(v);
        }
    }
    cout<<endl;
}

int LCA(int u, int v)//二分搜索求出到达公共祖先所需的最少步数
{
    if(deg[u] > deg[v]) swap(u, v);
    int hu = deg[u], hv = deg[v];
    int tu = u, tv = v;
    for(int det=hv-hu, i=0; det; det>>=1, i++)
        if(det&1) tv = fa[tv][i];
    if(tu == tv) return tu;
    for(int i=DEG-1; i>=0; i--)
        if(fa[tu][i] != fa[tv][i])
        {
            tu = fa[tu][i];
            tv = fa[tv][i];
        }
    return fa[tu][0];
}

#define root 1, n, 1
#define lson L, mid, rt<<1
#define rson mid+1, R, rt<<1|1
#define lr rt<<1
#define rr rt<<1|1

void Up(int rt)
{
    lca[rt] = LCA(lca[lr], lca[rr]);
}

void bulid(int L, int R, int rt)
{
    if(L == R)
    {
        lca[rt] = L;
        return ;
    }
    int mid = (L+R)>>1;
    bulid(lson);
    bulid(rson);
    Up(rt);
}

int Query(int l, int r, int L, int R, int rt)//求出区间[l, r]的LCA
{

    if(l==L && r==R)
    return lca[rt];

    int mid = (L+R)>>1;
    if(r <= mid) return Query(l, r, lson);
    else if(l>mid) return Query(l, r, rson);
    else return LCA(Query(l, mid, lson), Query(mid+1, r, rson));
}

int main()
{
    int n, q;
    while(~scanf("%d", &n))
    {
        init();
        int u, v;
        for(int i=0; i<n-1; i++)
        {
            scanf("%d%d", &u, &v);
            adde(u, v);
            adde(v, u);
        }
        BFS(1);
        bulid(root);
        scanf("%d", &q);
        for(int i=0; i<q; i++)
        {
            scanf("%d%d", &u, &v);
            printf("%d\n", Query(u, v, root));
        }
    }
    return 0;
}

时间: 2024-12-20 00:31:44

bestcoders pog love szhIII的相关文章

HDU 5266 pog loves szh III (LAC)

问题描述 pog在与szh玩游戏,首先pog在纸上画了一棵有根树,这里我们定义1为这棵树的根,然后szh在这棵树中选了若干个点,想让pog帮忙找找这些点的最近公共祖先在哪里,一个点为S的最近公共祖先当且仅当以该点为根的子树包含S中的所有点,且该点深度最大.然而,这个问题是十分困难的,出于szh对pog的爱,他决定只找编号连续的点,即l i   ~r i   . 输入描述 若干组数据(不超过3  组n≥10000  或Q≥10000  ). 每组数据第一行一个整数n(1≤n≤300000)  ,表

hdu 5265 pog loves szh II STL

pog loves szh II Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5265 Description pog在与szh玩游戏,首先pog找到了一个包含n个数的序列,然后他在这n个数中挑出了一个数A,szh出于对pog的爱,在余下的n−1个数中也挑了一个数B,那么szh与pog的恩爱值为(A+B)对p取模后的余数,pog与szh当然想让恩爱值越高越好,并且他们

HDU 5266 pog loves szh III ( LCA + SegTree||RMQ )

pog loves szh III Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 470    Accepted Submission(s): 97 Problem Description Pog and Szh are playing games. Firstly Pog draw a tree on the paper. He

HDU5265——贪心——pog loves szh II

Problem Description Pog and Szh are playing games.There is a sequence with $n$ numbers, Pog will choose a number A from the sequence. Szh will choose an another number named B from the rest in the sequence. Then the score will be $(A+B)$ mod $p$.They

hdu 5266 pog loves szh III 在线lca+线段树区间优化

题目链接:hdu 5266 pog loves szh III 思路:因为它查询的是区间上的lca,所以我们需要用在线lca来处理,达到单点查询的复杂度为O(1),所以我们在建立线段树区间查询的时候可以达到O(1*nlgn)的时间复杂度 ps:因为栈很容易爆,所以.....你懂的 -->#pragma comment(linker, "/STACK:1024000000,1024000000") /*****************************************

ACM学习历程—HDU5265 pog loves szh II(策略 &amp;&amp; 贪心 &amp;&amp; 排序)

Description Pog and Szh are playing games.There is a sequence with $n$ numbers, Pog will choose a number A from the sequence. Szh will choose an another number named B from the rest in the sequence. Then the score will be $(A+B)$ mod $p$.They hope to

hdu 5264 pog loves szh I 水题

pog loves szh I Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5264 Description pog拥有很多字符串,它喜欢将两个长度相等字符串交错拼在一起,如abcd与efgh,那么交错拼在一起就成了aebfcgdh啦!szh觉得这并不好玩,因此它将第二个字符串翻转了一遍,如efgh变成了hgfe,然后再将这两个字符串交错拼在一起,因此abcd与efg

hdu 5264 pog loves szh I

题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5264 pog loves szh I Description Pog has lots of strings. And he always mixes two equal-length strings. For example, there are two strings: "abcd" and "efgh". After mixing, a new string &q

字符串处理 BestCoder Round #43 1001 pog loves szh I

题目传送门 1 /* 2 字符串处理:是一道水题,但是WA了3次,要注意是没有加'\0'的字符串不要用%s输出,否则在多组测试时输出多余的字符 3 */ 4 #include <cstdio> 5 #include <algorithm> 6 #include <cstring> 7 #include <cmath> 8 using namespace std; 9 10 typedef long long ll; 11 const int MAXN = 1