zoukankan      html  css  js  c++  java
  • 关于二叉树某点到各点的距离问题

    题目链接
    题意:给你一颗满二叉树,给出每个的边权,第i条边连接第i+1和第(i+1)/2的点
    询问:x点到其他点的距离d[i] , d[i]-h>=0 的值累加的和
    题解:构造树前缀和,将其每个子节点到该节点的值预处理出来,利用前缀和数组二分查找
    具体看代码注释
    代码转自https://www.cnblogs.com/ogiso-setsuna/p/7911772.html

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pb push_back
    int n,m,L[1000005],a,h,tmp,lch,rch,last;
    ll ans=0;
    vector<int>d[1000005];//存储子节点到该节点的距离
    vector<ll>pre[1000005];//前缀数组
    ll query(int x,int h)//二分查找在第x节点中子节点小于等于h的的个数
    {
        if(h<=0) return 0;
        int p = upper_bound(d[x].begin(),d[x].end(),h)-d[x].begin();
        return 1ll*p*h-1ll*pre[x][p-1];//计算前缀和的累加
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=2;i<=n;i++) scanf("%d",&L[i]);
        for(int i=n;i>=1;--i)//构建二叉树
        {
            d[i].pb(0);//本身距离
            lch=i<<1;rch=i<<1 | 1;//左右子节点
            if(lch<=n)
            {
                for(int j=0;j<d[lch].size();j++) d[i].pb(d[lch][j]+L[lch]);
            }
            if(rch<=n)
            {
                for(int j=0;j<d[rch].size();j++)d[i].pb(d[rch][j]+L[rch]);
            }
            sort(d[i].begin(),d[i].end());
            pre[i].resize(d[i].size());///开辟大小
            for(int j=1;j<pre[i].size();j++)
            {
                pre[i][j]=pre[i][j-1]+d[i][j];///前缀和
            }
        }
        while(m--)
        {
            scanf("%d%d",&a,&h);
            ans=0;
            tmp=a;last=0;//last用与判断之前的下层是否访问过
            while(tmp)//从询问点,慢慢往上计算不属于该点的子节点的 点
            {
                if(h<0) break;
                ans+=h;//加上自己本身
                lch=tmp<<1;rch=tmp<<1|1;
                if(lch<=n&&lch!=last)
                {
                    ans+=query(lch,h-L[lch]);
                }
                if(rch<=n&&rch!=last)
                {
                    ans+=query(rch,h-L[rch]);
                }
                h-=L[tmp];last=tmp;tmp>>=1;//返回上一层
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Allegro PCB转换成PADS方法
    Altium Designer只显示某一层,隐藏其他层
    DCDC功率电感(Inductor)选型
    DDR布线教程
    DDR地址、容量计算、Bank理解
    DDR3中的ODT(On-die termination)
    LINUX文件系统操作指令之四
    linux系统之间通过nfs网络文件系统挂载设置方法
    linux消息队列编程实例
    system()函数
  • 原文地址:https://www.cnblogs.com/q1076452761/p/8033865.html
Copyright © 2011-2022 走看看