zoukankan      html  css  js  c++  java
  • hdu 5266 pog loves szh III(lca + 线段树)

    I - pog loves szh III
    Time Limit:6000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u

    Description

    Pog and Szh are playing games. Firstly Pog draw a tree on the paper. Here we define 1 as the root of the tree.Then Szh choose some nodes from the tree. He wants Pog helps to find the least common ancestor (LCA) of these node.The question is too difficult for Pog.So he decided to simplify the problems.The nodes picked are consecutive numbers from l_i to r_i ([l_i, r_i])

    Hint : You should be careful about stack overflow !

    Input

    Several groups of data (no more than 3 groups,n geq 10000 or Q geq 10000). 

    The following line contains ans integers,n (2 leq n leq 300000)

    AT The following n-1 line, two integers are b_i and c_i at every line, it shows an edge connecting b_i and c_i

    The following line contains ans integers,Q (Q leq 300000)

    AT The following Q line contains two integers li and ri(1 leq li leq ri leq n).

    Output

    For each case,output Q integers means the LCA of [l_i,r_i].

    Sample Input

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

    Sample Output

    1
    1
    3
    3
    1

    /*
    hdu 5266 pog loves szh III(lca + 线段树)
    
    problem:
    给你一棵树,然后查询节点l~r的最小公共祖先
    
    solve:
    如果用在线算法,查询的时候可以直接O(1)实现,然后查询节点l~r的最小公共祖先感觉很像区间最值
    而且可以发现 如果知道a~b和c~d的最小公共祖先,那么a~d的lca 就是a~b的lca和c~d的lca的最小公共祖先
    所以考虑用线段树解决查询问题
    
    hhh-2016-08-08 16:58:09
    */
    #pragma comment(linker,"/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    #include <map>
    #include <queue>
    #include <vector>
    #include <set>
    #define lson (i<<1)
    #define rson ((i<<1)|1)
    using namespace std;
    typedef long long ll;
    const int maxn=300000 + 500;
    const int INF=0x3f3f3f3f;
    const int mod = 1e9+7;
    int n,tot,cnt;
    int head[maxn],rmq[maxn];
    int flag[maxn];
    int vis[maxn];
    int P[maxn];
    int F[maxn<<1];
    
    struct Edge
    {
        int from,to,next;
    } edge[maxn << 1];
    
    int fin(int x)
    {
        if(F[x] == -1) return x;
        return F[x] = fin(F[x]);
    }
    
    void unio(int a,int b)
    {
        int ta=  fin(a);
        int tb= fin(b);
        if(ta != tb)
            F[ta] = tb;
    }
    
    void add_edge(int u,int v)
    {
        edge[tot].from = u,edge[tot].to = v,edge[tot].next=head[u],head[u] = tot++;
    }
    
    struct ST
    {
        int m[maxn << 1];
        int dp[maxn << 1][20];
        void ini(int n)
        {
            m[0] = -1;
            for(int i = 1; i <= n; i++)
            {
                m[i] = ((i&(i-1)) == 0)? m[i-1]+1:m[i-1];
                dp[i][0] = i;
            }
            for(int j = 1; j <= m[n]; j++)
            {
                for(int i = 1; i+(1<<j)-1 <= n; i++)
                    dp[i][j] = rmq[dp[i][j-1]] < rmq[dp[i+(1<<(j-1))][j-1]] ?
                               dp[i][j-1] : dp[i+(1 << (j-1))][j-1];
            }
        }
        int query(int a,int b)
        {
            if(a > b)
                swap(a,b);
            int k = m[b-a+1];
            return rmq[dp[a][k]] <= rmq[dp[b-(1<<k)+1][k]] ?
                   dp[a][k]:dp[b-(1<<k)+1][k];
        }
    };
    
    ST st;
    
    void dfs(int u,int pre,int dep)
    {
        F[++cnt] = u;
        rmq[cnt] = dep;
        P[u] = cnt;
    
        for(int i = head[u]; ~i; i = edge[i].next)
        {
            int v = edge[i].to;
            if(v == pre)
                continue;
            dfs(v,u,dep+1);
            F[++cnt] = u;
            rmq[cnt] = dep;
        }
    }
    
    int query_lca(int a,int b)
    {
        return F[st.query(P[a],P[b])];
    }
    void ini()
    {
        memset(flag,0,sizeof(flag));
        memset(head,-1,sizeof(head));
        tot =0;
        cnt = 0;
    }
    
    struct node
    {
        int l,r;
        int lca;
        int mid()
        {
            return (l+r)>>1;
        }
    } tree[maxn << 2];
    
    void push_up(int i)
    {
        tree[i].lca = query_lca(tree[lson].lca,tree[rson].lca);
    //    cout << tree[lson].lca << " " <<tree[rson].lca <<endl;
    //    cout << tree[i].l<< " " << tree[i].r << " "  <<tree[i].lca <<endl;
    }
    
    void build(int i,int l,int r)
    {
        tree[i].l = l,tree[i].r = r;
        if(l == r)
        {
            tree[i].lca = l;
    //        cout << tree[i].l<< " " << tree[i].r << " "  <<tree[i].lca <<endl;
            return ;
        }
        int mid = tree[i].mid();
        build(lson,l,mid);
        build(rson,mid+1,r);
        push_up(i);
    }
    
    int query(int i,int l,int r)
    {
        if(tree[i].l >= l && tree[i].r <= r)
        {
            return tree[i].lca;
        }
        int mid = tree[i].mid();
        if(r <= mid)
            return query(lson,l,r);
        else if(l > mid)
            return query(rson,l,r);
        else
            return query_lca(query(lson,l,mid),query(rson,mid+1,r));
        push_up(i);
    }
    
    int main()
    {
        int n,m,k;
        int a,b,c;
      //  freopen("in.txt","r",stdin);
        while(scanf("%d",&n) != EOF)
        {
            ini();
    
            for(int i = 1; i < n; i++)
            {
                scanf("%d%d",&a,&b);
                add_edge(b,a);
                add_edge(a,b);
                flag[b] = 1;
            }
            dfs(1,1,0);
            st.ini(2*n-1);
            scanf("%d",&m);
            build(1,1,n);
           // printf("1 2 %d
    ",query_lca(1,2));
            for(int i = 1; i <= m; i++)
            {
                scanf("%d%d",&a,&b);
                printf("%d
    ",query(1,a,b));
    //printf("%d
    ",query_lca(a,b));
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    第010讲~第011讲:一个打了激素的数组
    练习15--阅读文件
    第007讲~第009讲:了不起的分支和循环
    第006讲:Python之常用操作符
    第005讲:闲聊之python的数据类型
    练习14--提示和传递
    第004讲:改进我们的小游戏
    ICPC Central Europe Regional Contest 2019 H. Ponk Warshall
    2019 ICPC Asia Yinchuan Regional G. Pot!!(线段树 区间更新 区间查询)
    CF1286A Garland
  • 原文地址:https://www.cnblogs.com/Przz/p/5757303.html
Copyright © 2011-2022 走看看