zoukankan      html  css  js  c++  java
  • NKOJ P3815 树上的询问 (LCA 倍增)(复习距离倍增)

    评测说明 : 1000ms
    问题描述

    现有一棵 n 个节点的树,树上每条边的长度均为 1。给出 m 个询问,每次询问两个节 点 x,y,求树上到 x,y 两个点距离相同的节点数量。 

    输入格式

    第一个整数 n,表示树有 n 个点。
    接下来 n-1 行每行两整数 a,b,表示从 a 到 b 有一条边。
    接下来一行一个整数 m,表示有 m 个询问。
    接下来 m 行每行两整数 x,y,询问到 x 和 y 距离相同的点的数量。 

    输出格式

    共 m 行,每行一个整数表示询问的答案。 

    样例输入


    1 2 
    1 3 
    2 4 
    2 5 
    3 6 
    3 7 

    1 2 
    4 5
    2 3 

     
     
     
    思路: 被坑了好久 一直没调出来  复习了一波LCA 后 终于A 了 注意 倍增的用法 即GOUP 操作
     
    顺便复习一下 距离倍增 
    code:
    g[x][i]=g[x][i-1]+g[fa[x][i-1]][i-1];

    dis 求法

    for(i=0;i<=ss;i++)
        if(k&(1<<i))dis+=g[x][i],x=fa[x][i];
    if(x==y)return dis;
    for(i=s;i>=0;i--)
            if(fa[x][i]!=fa[y][i])
            {
                dis+=g[x][i];x=fa[x][i];
    
                dis+=g[y][i];y=fa[y][i];
            }
        return dis+=g[x][0]+g[y][0];
     
    code:
    //
    #include<bits/stdc++.h>
    using namespace std;
    #define maxnn 600000
    int f[maxnn][100];
    int las[maxnn],nex[maxnn],en[maxnn],tot;
    int n,m;
    int dep[maxnn];
    int x,y;
    int size[maxnn];
    void dfs(int v,int fa)
    {
        dep[v]=dep[fa]+1;
        f[v][0]=fa;
        int s=ceil(log2(n));
        for(int i=1;i<=s;i++)
        {
            f[v][i]=f[f[v][i-1]][i-1];
        }
        for(int i=las[v];i;i=nex[i])
        {
            int u=en[i];
            if(u!=fa)
            {
                dfs(u,v);
                size[v]+=size[u];
            }
        }
        return ;
    }
    void add(int a,int b)
    {
        en[++tot]=b;
        nex[tot]=las[a];
        las[a]=tot;
    }
    int goup(int x,int s)
    {
        int k=ceil(log2(n));
        for(int i=0;i<=k;i++)
        {
            if((s&(1<<i)))
            {
                x=f[x][i];
            }
        }
        return x;
    }
    int lca(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        x=goup(x,dep[x]-dep[y]);
        if(x==y) return y;
        int s=ceil(log2(dep[x]));
        for(int i=s;i>=0;i--)
        {
            if(f[x][i]!=f[y][i])
            {
                x=f[x][i];
                y=f[y][i];
            }
        }
        return f[x][0];
    }
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++) size[i]=1;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs(1,0);
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            int k1=0,k=0;
            scanf("%d%d",&x,&y);
            if(y==x) {cout<<n<<endl;continue;}
            if(dep[x]==dep[y])
            {
                int k=dep[x]-dep[lca(x,y)];
                int k1=n-size[goup(x,k-1)]-size[goup(y,k-1)];
                cout<<k1<<endl;
                continue;
            }
            if((abs((dep[x]-dep[y])))&1) {cout<<0<<endl;continue;}
            if(dep[x]<dep[y])
            swap(x,y);
            k=(dep[y]+dep[x]-2*dep[lca(x,y)])/2;
            int p1=goup(x,k-1);int p2=goup(x,k);
            k1=size[p2]-size[p1];
            cout<<k1<<endl;
            
        } 
     } 
    刀剑映出了战士的心。而我的心,漆黑且残破
  • 相关阅读:
    ASP.NET服务器控件开发(3)事件和回传数据的处理
    ASP.NET服务器控件开发(1)封装html
    .Net Remoting(基本操作) Part.2
    javascript方法和技巧大全_javascript教程
    .Net Remoting(分离服务程序实现) Part.3
    [转]我在面试.NET/C#程序员时会提出的问题
    ASP.NET服务器控件开发(2)继承WebControl类
    一点点对WebResource.axd的配置及使用[原创]
    .Net Remoting(远程方法回调) Part.4
    ASP.NET自定义控件复杂属性声明持久性浅析
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11324624.html
Copyright © 2011-2022 走看看