zoukankan      html  css  js  c++  java
  • 北方多校 又是一道简单题

    又是一道简单题

      •  12000ms
      •  65536K

    给出一棵有根树,每次查询给出两个节点 u 和 v,假设节点 f 是u,v的最近公共祖先,请查询以 f 为根的子树中,不在 u 到 v 这条链上且标号最小的节点。

    输入格式

    第一行输入正整数 T(T <= 30),表示共有T组输入数据。

    对于每组数据,第一行输入两个正整数 n,m(n <= 50000,m <= 50000),表示节点数和询问数,节点编号 1 到 n,其中 1 是根节点。

    接下来 n - 1 行,每行输入两个正整数u,v,表示标号为u和v的节点间有一条边。

    接下来 m 行,每行输入两个正整数u,v,表示一次询问。

    保证所有输入数据均合法。

    输出格式

    对于每次询问,输出答案。如不存在输出-1。

    样例输入

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

    样例输出

    3
    2
    -1
    分析:考虑树链剖分;
       把子树按dfs序可以展开到一维,然后对于链,可以将这个区间分成logn的部分,对于每个部分求最小值即可;
       复杂度nlognlogn;
    代码:
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <bitset>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <cassert>
    #include <ctime>
    #define rep(i,m,n) for(i=m;i<=n;i++)
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define vi vector<int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define pi acos(-1.0)
    #define pii pair<int,int>
    #define ls rt<<1
    #define rs rt<<1|1
    #define sys system("pause")
    const int maxn=1e5+10;
    const int N=1e5+10;
    using namespace std;
    ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
    ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p%mod;p=p*p%mod;q>>=1;}return f;}
    int n,m,k,t,st[maxn],ed[maxn],dep[maxn],fa[20][maxn],bel[maxn],son[maxn],pos[maxn],a[maxn],dfs_cl,mi[maxn<<2];
    vi e[maxn];
    void dfs1(int x,int y)
    {
        dep[x]=dep[y]+1;
        fa[0][x]=y;
        son[x]=1;
        for(int i=1;fa[i-1][fa[i-1][x]];i++)
        {
            fa[i][x]=fa[i-1][fa[i-1][x]];
        }
        for(int i=0;i<e[x].size();i++)
        {
            int z=e[x][i];
            if(z==y)continue;
            dfs1(z,x);
            son[x]+=son[z];
        }
    }
    void dfs2(int x,int y,int ch)
    {
        int ma=0;
        pos[x]=++dfs_cl;
        st[x]=dfs_cl;
        a[dfs_cl]=x;
        bel[x]=ch;
        for(int i=0;i<e[x].size();i++)
        {
            int z=e[x][i];
            if(z==y)continue;
            if(son[z]>son[ma])ma=z;
        }
        if(ma!=0)dfs2(ma,x,ch);
        for(int i=0;i<e[x].size();i++)
        {
            int z=e[x][i];
            if(z==y||z==ma)continue;
            dfs2(z,x,z);
        }
        ed[x]=dfs_cl;
    }
    int lca(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        for(int i=19;i>=0;i--)if(dep[fa[i][x]]>=dep[y])x=fa[i][x];
        if(x==y)return x;
        for(int i=19;i>=0;i--)
        {
            if(fa[i][x]!=fa[i][y])x=fa[i][x],y=fa[i][y];
        }
        return fa[0][x];
    }
    void pup(int l,int r,int rt)
    {
        mi[rt]=min(mi[ls],mi[rs]);
    }
    void build(int l,int r,int rt)
    {
        if(l==r)
        {
            mi[rt]=a[l];
            return;
        }
        int mid=l+r>>1;
        build(l,mid,ls);
        build(mid+1,r,rs);
        pup(l,r,rt);
    }
    int gao(int L,int R,int l,int r,int rt)
    {
        if(L==l&&R==r)return mi[rt];
        int mid=l+r>>1;
        if(R<=mid)return gao(L,R,l,mid,ls);
        else if(L>mid)return gao(L,R,mid+1,r,rs);
        else return min(gao(L,mid,l,mid,ls),gao(mid+1,R,mid+1,r,rs));
    }
    void upd(vector<int>&a,int x,int y)
    {
        while(bel[x]!=bel[y])
        {
            if(dep[bel[x]]<dep[bel[y]])swap(x,y);
            a.pb(pos[x]);
            a.pb(pos[bel[x]]);
            x=fa[0][bel[x]];
        }
        if(pos[x]>pos[y])swap(x,y);
        a.pb(pos[y]);
        a.pb(pos[x]);
    }
    int main()
    {
        int i,j;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            rep(i,1,n)e[i].clear();
            rep(i,1,n)rep(j,0,19)fa[j][i]=0;
            rep(i,1,n-1)scanf("%d%d",&j,&k),e[j].pb(k),e[k].pb(j);
            dfs1(1,0);
            dfs_cl=0;
            dfs2(1,0,1);
            build(1,n,1);
            while(m--)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                vector<int>tmp;
                int lc=lca(x,y);
                upd(tmp,x,y);
                int s=st[lc],t=ed[lc];
                if(lc<1||lc>n)return 0;
                sort(tmp.begin(),tmp.end());
                int mi=1e9;
                for(i=0;i<tmp.size();i+=2)
                {
                    if(s<=tmp[i]-1)mi=min(mi,gao(s,tmp[i]-1,1,n,1));
                    s=tmp[i+1]+1;
                }
                if(s<=t)mi=min(mi,gao(s,t,1,n,1));
                printf("%d
    ",mi==1e9?-1:mi);
            }
        }
        return 0;
    }
  • 相关阅读:
    使用 asp.net mvc和 jQuery UI 控件包
    ServiceStack.Redis 使用教程
    HTC T8878刷机手册
    Entity Framework CodeFirst 文章汇集
    2011年Mono发展历程
    日志管理实用程序LogExpert
    使用 NuGet 管理项目库
    WCF 4.0路由服务Routing Service
    精进不休 .NET 4.0 (1) asp.net 4.0 新特性之web.config的改进, ViewStateMode, ClientIDMode, EnablePersistedSelection, 控件的其它一些改进
    精进不休 .NET 4.0 (7) ADO.NET Entity Framework 4.0 新特性
  • 原文地址:https://www.cnblogs.com/dyzll/p/6973627.html
Copyright © 2011-2022 走看看