• 聪聪可可


    树分治,每次统计时有两种组合%3==2和%3==1, %3==0和%3==0
    乘法原理即可

    # include <stdio.h>
    # include <stdlib.h>
    # include <iostream>
    # include <algorithm>
    # include <string.h>
    # define IL inline
    # define RG register
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    
    IL ll Read(){
        RG char c = getchar(); RG ll x = 0, z = 1;
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
        return x * z;
    }
    
    const int MAXN(40010), INF(2147483647);
    int n, cnt, fst[MAXN], to[MAXN], nxt[MAXN], w[MAXN];
    int size[MAXN], rt, sz, mx[MAXN], vis[MAXN];
    ll d[3], num;
    
    IL void Add(RG int u, RG int v, RG int f){  nxt[cnt] = fst[u]; to[cnt] = v; w[cnt] = f; fst[u] = cnt++;  }
    
    IL void Getroot(RG int u, RG int fa){
        size[u] = 1; mx[u] = 0;
        for(RG int e = fst[u]; e != -1; e = nxt[e]){
            if(vis[to[e]] || fa == to[e]) continue;
            Getroot(to[e], u);
            size[u] += size[to[e]];
            mx[u] = max(mx[u], size[to[e]]);
        }
        mx[u] = max(mx[u], sz - size[u]);
        if(mx[u] < mx[rt]) rt = u;
    }
    
    IL void Getdeep(RG int u, RG int fa, RG int dis){
        d[dis % 3]++;
        for(RG int e = fst[u]; e != -1; e = nxt[e]){
            if(vis[to[e]] || fa == to[e]) continue;
            Getdeep(to[e], u, (dis + w[e]) % 3);
        }
    }
    
    IL ll Calc(RG int u, RG int ww){
        d[0] = d[1] = d[2] = 0;
        Getdeep(u, 0, ww);
        return d[1] * d[2] * 2 + d[0] * d[0];
    }
    
    IL void Solve(RG int u){
        vis[u] = 1; num += Calc(u, 0);
        for(RG int e = fst[u]; e != -1; e = nxt[e]){
            if(vis[to[e]]) continue;
            num -= Calc(to[e], w[e]);
            rt = 0; sz = size[to[e]];
            Getroot(to[e], u);
            Solve(rt);
        }
    }
    
    IL ll Gcd(RG ll a, RG ll b){  return !a ? b : Gcd(b % a, a);  }
    
    int main(RG int argc, RG char* argv[]){
        n = Read(); Fill(fst, -1);
        for(RG int i = 1; i < n; i++){
            RG int u = Read(), v = Read(), f = Read();
            Add(u, v, f); Add(v, u, f);
        }
        mx[0] = INF; sz = n; Getroot(1, 0); Solve(rt);
        RG ll a = num, b = 1LL * n * n, g = Gcd(a, b);
        printf("%lld/%lld
    ", a / g, b / g);
        return 0;
    }
  • 相关阅读:
    左侧列固定的表格
    百度地图上添加多个标记,标记上添加信息展示窗口、跳转到导航界面
    vue-cli4版本解决eslint问题
    使用脚手架搭建项目
    正则表达式学习
    函数参数:
    装饰器(重点)
    列表生成式、生成器、迭代器
    logging 日志模块
    json 、 pickle 、shelve序列化
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206386.html
Copyright © 2020-2023  润新知