瀋陽網絡賽 D Fish eating fruit(點分治)

State Z is a underwater kingdom of the Atlantic Ocean. This country is amazing. There are nn cities in the country and n-1n−1 undirected underwater roads which connect all cities.

In order to save energy and avoid traffic congestion, the king promulgated a series of traffic regulations:

  1. Residents have to travel on fish!

  2. Residents need to feed the fish before you start your trip!The amount of food you feed the fish should be exactly the total distance of your journey.

  3. What kind of food to feed depends on the total distance of your journey!Total distance is a multiple of three. You should feed the fish with Durian. Total distance modulus 33 equaling 11. It should be Papaya.Total distance modulus 33 equaling 22. It should be Avocado!!!

Sure, fish like to eat these fruits very much.

Today is the first day of the king's decree. Because the residents here are not good at mathematics, they don't know how much fruit they need to give fish to go to other cities. So the king give an order to the energy minister Ynaonlctrm From all cities to all cities directly, which means that he will make n*(n-1)n∗(n−1) trips.

For example, A - (5 mile) - B - (5 mile) - C, he needs to run the fish, starting at A, passing B, finally arriving C (papaya 10 kg), also he needs to start at C and end at A (papaya 10 kg). Indirect passage is useless. "I've passed City B, my dear emperor." "Oh! It's no use! Not directly! People in cities will never know how much the fish need to eat! The fish will surely die!!! You also need to take several trips which start at B or end with B!" The Emperor said.

It's really a tough task. Can you help him figure out how much fruit he needs to prepare for the emperor's mission?

Input

Multiple input!

Fist line is NN. next N-1N−1 line has three integer aa, bb and cc. It represent city aa and city bb is connected by a road of cc nautical miles. (1<n \le 10^41<n≤104, 0 \le a,b<n0≤a,b<n, 1 \le c<10^51≤c<105, \sum{n} \le 10^5∑n≤105)

Output

For each data, output three number, the amount of Durian, Papaya and Avocado he need. (the result could be very large, please output the result mod 10^9+7109+7)

樣例輸入1複製

5
0 1 2
0 2 3
0 3 7
0 4 6

樣例輸出1複製

54 60 30

樣例輸入2複製

8
4 7 1
7 5 1
4 6 1
6 3 1
5 2 1
2 1 1
7 0 1

樣例輸出2複製

48 54 48

   求距離%3等於0,1,2的點對各有多少。

   點分治即可,注意取模和每次cal怎樣O(n)求符合條件點對。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 20005;
const int inf = 0x3f3f3f3f;
const long long mod = 1e9 + 7;
int head[maxn], cnt, vis[maxn], n, allnode;
int root, son[maxn], maxSon[maxn], dis[maxn], deep[maxn];
long long ans0 = 0, ans1 = 0, ans2 = 0;
inline bool sc(int &num) {
	char in; bool IsN = false;
	in = getchar();
	if (in == EOF) return false;
	while (in != '-' && (in<'0' || in>'9')) in = getchar();
	if (in == '-') { IsN = true; num = 0; }
	else num = in - '0';
	while (in = getchar(), in >= '0'&&in <= '9') {
		num *= 10, num += in - '0';
	}
	if (IsN) num = -num;
	return true;
}
struct fuck {
	int u, v, ne, w;
}edis[maxn << 1];
struct an {
	long long ans0, ans1, ans2;
};
inline void init() {
	for (int i = 0; i <= n + 1; i++) {
		head[i] = -1;
		vis[i] = 0;
	}
	cnt = root = ans1 = ans2 = ans0 = 0; maxSon[0] = inf;
	allnode = n;
}
inline void add(int u, int v, int w) {
	edis[cnt].u = u; edis[cnt].v = v; edis[cnt].w = w;
	edis[cnt].ne = head[u]; head[u] = cnt++;
}
inline void getRoot(int u, int fa) {
	son[u] = 1; maxSon[u] = 0;
	for (int s = head[u]; ~s; s = edis[s].ne) {
		int v = edis[s].v;
		if (v == fa || vis[v])continue;
		getRoot(v, u);
		son[u] += son[v];
		maxSon[u] = max(maxSon[u], son[v]);
	}
	maxSon[u] = max(maxSon[u], allnode - son[u]);
	if (maxSon[u] < maxSon[root])root = u;
}
inline void getDeep(int x, int fa) {
	deep[++deep[0]] = dis[x];
	for (int s = head[x]; ~s; s = edis[s].ne) {
		int v = edis[s].v;
		if (v == fa || vis[v])continue;
		dis[v] = dis[x] + edis[s].w;
		getDeep(v, x);
	}
}
inline an cal(int x, int now) {
	dis[x] = now; deep[0] = 0;
	getDeep(x, 0);
	long long sum1 = 0, sum0 = 0, sum2 = 0;
	long long num1 = 0, num0 = 0, num2 = 0;
	for (int i = 1; i <= deep[0]; i++) {
		if (deep[i] % 3 == 0)
			sum0 += deep[i], num0++, sum0 %= mod;
		else if (deep[i] % 3 == 1)
			sum1 += deep[i], num1++, sum1 %= mod;
		else sum2 += deep[i], num2++, sum2 %= mod;
	}
	an all;
	all.ans0 = ((num2*sum1%mod + num1 * sum2%mod) % mod * 2 + sum0 * num0%mod * 2) % mod;
	all.ans1 = ((num1*sum0%mod + num0 * sum1%mod) % mod * 2 + sum2 * num2%mod * 2) % mod;
	all.ans2 = ((num2*sum0%mod + num0 * sum2%mod) % mod * 2 + sum1 * num1%mod * 2) % mod;
	return all;
}
inline void getDfs(int st) {
	vis[root] = 1;
	an res = cal(st, 0);
	ans0 = (ans0 + res.ans0) % mod;
	ans1 = (ans1 + res.ans1) % mod;
	ans2 = (ans2 + res.ans2) % mod;
	for (int s = head[root]; ~s; s = edis[s].ne) {
		int v = edis[s].v;
		if (vis[v])continue;
		an tmp = cal(v, edis[s].w);
		ans0 = (ans0 + mod - tmp.ans0) % mod;
		ans1 = (ans1 + mod - tmp.ans1) % mod;
		ans2 = (ans2 + mod - tmp.ans2) % mod;
		allnode = son[v];
		root = 0; getRoot(v, st);
		getDfs(root);
	}
}
int main() {
	while (~scanf("%d", &n)) {
		init();
		for (int s = 1; s < n; s++) {
			int a, b, c;
			sc(a); sc(b); sc(c);
			a++; b++;
			add(a, b, c); add(b, a, c);
		}
		getRoot(1, -1);
		getDfs(root);
		printf("%lld %lld %lld\n", ans0, ans1, ans2);
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章