• Codeforces Round #425 (Div. 2) -D


    题目大意:给你一棵树,有 q 个询问,每次给你三个数,其中一个当做终点,两个当做起点,问你这样两条路有多少公共节点。

    思路:LCA,如果只问你 a,b 分别到 c 的两条路有多少个公共节点的话,就是( dis( a , c) + dis( b , c) - dis( a , b ) ) / 2 + 1 ;

    所以我们知道求出每两个点之间的最短距离,(最长的 + 第二长 - 最短的)/ 2 + 1;

    #include<bits/stdc++.h>
    #define pb push_back
    using namespace std;
    const int N=1e5+5;
    int vs[2*N],dp[2*N][25],d[N],tot=0,f[N],w[3];
    vector<int> e[N];
    int n,q;
    void dfs(int u,int p,int s)
    {
        vs[++tot]=u;
        d[u]=s;
        f[u]=tot;
        for(int i=0;i<e[u].size();i++)
        {
            int to=e[u][i];
            if(to==p) continue;
            dfs(to,u,s+1);
            vs[++tot]=u;
        }
    }
    void work_rmq()
    {
        for(int i=1;i<=tot;i++) dp[i][0]=vs[i];
        int up=log(tot)/log(2);
        for(int j=1;j<=up;j++)
        {
            int t=(1<<j)-1;
            for(int i=1;i+t<=tot;i++)
            {
                int a=dp[i][j-1],b=dp[i+(1<<(j-1))][j-1];
                if(d[a]<=d[b]) dp[i][j]=a;
                else dp[i][j]=b;
            }
        }
    }
    int get_lca(int u,int v)
    {
        int l,r;
        if(f[u]<f[v]) l=f[u],r=f[v];
        else l=f[v],r=f[u];
        int j=log(r-l+1)/log(2);
        int a=dp[l][j],b=dp[r-(1<<j)+1][j];
        if(d[a]<d[b]) return a;
        else return b;
    }
    int get_dis(int u,int v)
    {
        int f=get_lca(u,v);
        int res=fabs(d[u]-d[f])+fabs(d[v]-d[f]);
        return res;
    }
    int main()
    {
        cin>>n>>q;
        for(int i=2;i<=n;i++)
        {
            int g; scanf("%d",&g);
            e[i].pb(g); e[g].pb(i);
        }
        dfs(1,-1,0);
        work_rmq();
        while(q--)
        {
            int ans[3];
            for(int i=0;i<=2;i++) scanf("%d",&w[i]);
            ans[0]=get_dis(w[0],w[1]);
            ans[1]=get_dis(w[0],w[2]);
            ans[2]=get_dis(w[1],w[2]);
            sort(ans,ans+3);
            printf("%d
    ",(ans[2]+ans[1]-ans[0])/2+1);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    晨考总结第二天
    晨考总结第一天
    常用的设计模式总结
    AOP底层原理剖析
    Spring AOP
    jstat统计输出说明
    zabbix 触发器匹配字符串告警
    hive部分常用函数
    nginx日志说明
    windwos文件句柄数限制
  • 原文地址:https://www.cnblogs.com/CJLHY/p/7325132.html
Copyright © 2020-2023  润新知