zoukankan      html  css  js  c++  java
  • Tree

    对于每一条连到当前根的比k小的边edge,找比k-edge小的,不难想到树状数组。

    比较坑的是树状数组一定要定义局部变量,不然会奇妙WA哈哈。

    看一下代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,k;
    const int maxn=100000;
    int beg[maxn],nex[maxn],to[maxn],w[maxn],e;
    void add(int x,int y,int z){
        e++;nex[e]=beg[x];
        beg[x]=e;to[e]=y;w[e]=z;
    }
    #define inf 1e9
    int rt,mx,size;
    int sz[maxn],son[maxn],vis[maxn];
    inline void getrt(int x,int fa){
        sz[x]=1,son[x]=0;
        for(int i=beg[x];i;i=nex[i]){
            int t=to[i];
            if(vis[t]||t==fa)continue;
            getrt(t,x);
            sz[x]+=sz[t];
            if(son[x]<sz[t])son[x]=sz[t];
        }
        if(son[x]<size-sz[x])son[x]=size-sz[x];
        if(mx>son[x])mx=son[x],rt=x;
    }
    int q[maxn],ans,top;
    inline void stk(int x,int fa,int val){
        if(val>k)return;
        if(val==k){
            ans++;
            return;
        }
        q[++top]=val;
        for(int i=beg[x];i;i=nex[i]){
            int t=to[i];
            if(vis[t]||t==fa)continue;
            stk(t,x,val+w[i]);
        }
    }
    inline int lowbit(int x){
        return x&(-x);
    }
    inline void divide(int x){
        //printf("%d
    ",x);
        vis[x]=1;
        int c[k+10]={0};
        for(int i=beg[x];i;i=nex[i]){
            int t=to[i];
            if(vis[t])continue;
            top=0;
            stk(t,x,w[i]);
            ans+=top;
            //printf("%d %d %d %d ",t,x,top,ans);
            for(int j=1;j<=top;j++){
                int tmp=k-q[j];
                while(tmp){
                    ans+=c[tmp];
                    tmp-=lowbit(tmp);
                }
            }
            //printf("%d
    ",ans);
            for(int j=1;j<=top;j++){
                int tmp=q[j];
                while(tmp<=k){
                    c[tmp]++;
                    tmp+=lowbit(tmp);
                }
            }
            mx=inf,size=sz[t],rt=0;
            getrt(t,x);
            divide(rt);
        }
        //printf("%d %d
    ",qwq,x);
    }
    int main(){
        cin>>n;
        int x,y,z;
        for(int i=1;i<n;i++){
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);add(y,x,z);
        }
        cin>>k;
        mx=inf,rt=0,size=n;
        getrt(1,0);
        divide(rt);
        printf("%d
    ",ans);
        return 0;
    }

    努力想想的我一遍A了。

  • 相关阅读:
    转:1分钟解决git clone 速度慢的问题
    进程冻结学习笔记
    RT调度学习笔记(1)
    tracer ftrace笔记(2)——添加与使用
    Regeultor内核文档翻译_学习笔记
    一、Linux cpuidle framework(1)_概述和软件架构
    Python 将私有包自动上传Nexus私服
    Pychram 取消自动添加版本控制
    Python 3DES CBC 模式加密解密
    1588. 所有奇数长度子数组的和
  • 原文地址:https://www.cnblogs.com/syzf2222/p/12386763.html
Copyright © 2011-2022 走看看