zoukankan      html  css  js  c++  java
  • 牛客 城市网络(倍增)

    这题暴力思路是一直往上跳,然后计算,但是我们发现,如果知道了父节点的所有信息,那么我们只需要比一下父节点的信息和自己,就知道自己能怎么跳

    问题就是如何快速求信息,因此想到从根节点往下求,用倍增算法。我们是设f[i][j]为i能够交易2的j次的点在哪,所以只要知道f[i][0]就可以通过倍增思想求出所有。

    现在的问题就是如果求f[i][0],因为我们从父节点往下求,因此现在知道所有父节点信息,所以拿父节点的信息和自己比大小,跳到小于等于自己的最远距离

    存在两种情况,一是父节点就比自己大,第二个就是在刚刚走到的位置再往上一格。

    所有跳出根或者到不了的都为0,因为初始为c,只要多一条c和出发点的边就行。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=3e5+10;
    int f[N][21];
    int to[N];
    int depth[N];
    int e[N],ne[N],h[N],idx;
    int a[N];
    void add(int a,int b){
        e[idx]=b,ne[idx]=h[a],h[a]=idx++;
    }
    int n,q;
    void dfs(int u,int fa){
        int i;
        int x=fa;
        for(i=20;i>=0;i--){
            if(f[x][i]&&a[f[x][i]]<=a[u])//一直跳直到不能跳
                x=f[x][i];
        }
        if(a[x]>a[u]) //判断是否u的父节点就大于u
            f[u][0]=x;
        else{
            f[u][0]=f[x][0];
        }
        depth[u]=depth[fa]+1;//根据深度判断是否已经跳过目标点
        for(i=1;i<=20;i++)
            f[u][i]=f[f[u][i-1]][i-1];
        for(i=h[u];i!=-1;i=ne[i]){
            int j=e[i];
            if(j==fa)
                continue;
            dfs(j,u);
        }
    }
    int main(){
        cin>>n>>q;
        memset(h,-1,sizeof h);
        int i;
        for(i=1;i<=n;i++) scanf("%d",&a[i]);
        for(i=1;i<n;i++){
            int x,b;
            scanf("%d%d",&x,&b);
            add(x,b);
            add(b,x);
        }
        for(i=n+1;i<=n+q;i++){
            int x,b,c;
            scanf("%d%d%d",&x,&b,&c);
            add(x,i);
            a[i]=c;
            to[i-n]=b;
        }
        dfs(1,0);
        ll ans=0;
        for(i=1;i<=q;i++){
            int v=to[i];
            ans=0;
            int u=i+n;
            for(int j=20;j>=0;j--){
                if(depth[f[u][j]]>=depth[to[i]]){ //根据深度判断,因为树已经重构,不知道v在哪
                    ans+=1<<j;
                    u=f[u][j];
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    LINUX内核参数调优集锦
    性能测试基础-开门篇3(LR常用函数介绍)
    高并发WEB服务的演变
    数据链路层学习之LLDP
    Win8.1 Metro应用无法联网终极解决方法
    Win8.1 Metro应用无法联网,提示“无法加载此页面”解决方法!(看红色字体部分)
    SecureCrt脚本(三)二级对象之Screen详解
    SecureCrt自动化
    Python数据类型一:数字与运算符
    高阶函数
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12863185.html
Copyright © 2011-2022 走看看