Solution - P2634 [国家集训队] 聪聪可可
宏定义展开的锅。
思路
极简点分治。
思路显然,每次到的时候算贡献在上传就行了。
代码
#include <bits/stdc++.h>
#define rint register int
#define rllong register long long
#define llong long long
#define N 20004
using namespace std;
int to[N<<1], val[N<<1], nxt[N<<1], head[N], gsiz;
#define mkarc(u,v,w) (++gsiz, to[gsiz]=v, val[gsiz]=w, nxt[gsiz]=head[u], head[u]=gsiz)
int dp[N][3];
int n, ans;
#define mod(m) (((m)%3+3)%3)
inline int gcd(rint a, rint b){return b ? gcd(b, a%b) : a;}
inline void dfs(rint u, rint fa){
dp[u][0] = 1;
for(rint i = head[u]; i; i = nxt[i]){
rint v = to[i];
if(v == fa) continue;
dfs(v, u);
for(rint m = 0; m < 3; ++m) ans += (dp[v][m]*dp[u][mod(-m-val[i])])*2;
for(rint m = 0; m < 3; ++m) dp[u][mod(m+val[i])] += dp[v][m];
}
return;
}
int main(){
scanf("%d", &n);
for(rint i = 1; i < n; ++i){
rint u, v, w;
scanf("%d %d %d", &u, &v, &w), w = mod(w);
mkarc(u, v, w), mkarc(v, u, w);
}
dfs(1, 0);
rint a = ans+n, b = n*n, d = gcd(a, b);
printf("%d/%d", a/d, b/d);
return 0;
}
/*
5
1 2 1
1 3 2
1 4 1
2 5 3
*/

浙公网安备 33010602011771号