• 洛谷 P2634 [国家集训队]聪聪可可(点分治)


    传送门
    在做一道点分治练练手。
    主要就是求树上长度为 (3) 的倍数的路径的数量,当然还是用点分治更方便
    记录路径长度 (\%3) 后的数的数量,然后通过当前路径找能和它凑成 (3) 的倍数的路径有多少条
    由于是一个偏序,所以答案要 ( imes 2),当然还要加 (i->i) 的方案总共 (n) 条。

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=2e4+10;
    int n;
    int head[MAXN],to[MAXN*2],nxt[MAXN*2],val[MAXN*2],tot;
    int siz[MAXN],maxp[MAXN],sum,rt,dead[MAXN];
    int path[4],cnt,dis[MAXN],ans;
    
    void add(int u,int v,int w){
        to[++tot]=v;nxt[tot]=head[u];val[tot]=w;head[u]=tot;
    }
    
    void getrt(int u,int fa){
        siz[u]=1;maxp[u]=0;
        for(int i=head[u];i;i=nxt[i]){
            if(to[i]==fa||dead[to[i]]) continue;
            getrt(to[i],u);
            siz[u]+=siz[to[i]];
            maxp[u]=max(maxp[u],siz[to[i]]);
        }
        maxp[u]=max(maxp[u],sum-siz[u]);
        if(maxp[u]<maxp[rt]) rt=u;
    }
    
    void getdis(int u,int fa,int w){
        dis[++cnt]=w;
        for(int i=head[u];i;i=nxt[i]){
            if(to[i]==fa||dead[to[i]]) continue;
            getdis(to[i],u,w+val[i]);
        }
    }
    
    void calc(int u){
        path[0]=1;
        for(int i=head[u];i;i=nxt[i]){
            if(dead[to[i]]) continue;
            cnt=0;
            getdis(to[i],u,val[i]);
            for(int j=1;j<=cnt;j++)
                if(dis[j]%3==0) ans+=path[0];
                else ans+=path[3-dis[j]%3];
            for(int j=1;j<=cnt;j++) path[dis[j]%3]++;
        }
        memset(path,0,sizeof(path));
    }
    
    void divide(int u){
        dead[u]=1;
        calc(u);
        for(int i=head[u];i;i=nxt[i]){
            if(dead[to[i]]) continue;
            maxp[rt=0]=sum=siz[to[i]];
            getrt(to[i],0);
            getrt(rt,0);
            divide(rt);
        }
    }
    
    int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("data.in","r",stdin);
        freopen("data.out","w",stdout);
    #endif
        scanf("%d",&n);
        for(int i=1,u,v,w;i<n;i++){
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);add(v,u,w);
        }
        maxp[0]=sum=n;
        getrt(1,0);
        getrt(rt,0);
        divide(rt);
        ans=ans*2+n;
        int a=ans,b=n*n,d=gcd(a,b);
        printf("%d/%d
    ",a/d,b/d);
        return 0;
    }
    
  • 相关阅读:
    php测试题整理(0519)
    Ajax调用返回json,xml数据类型(0517--pm)
    python 收集测试日志--格式
    python3下tomorow模块报语法错误def async(n, base_type, timeout=None): ^ SyntaxError: invalid syntax
    appium 下载
    VMware 虚拟机设置固定ip
    Centos7 安装配置 SVN
    【Linux】 Centos7 安装 mysql-8.0
    win7 SP1 64位 原版 百度网盘下载
    win10操作系统 64位 原版 百度网盘下载
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12302574.html
Copyright © 2020-2023  润新知