2019瀋陽のネットワークゲームの魚を食べるフルーツ

3ヶ月間に見えたこのタイトルは、最終的には木がDPを学ぶことがなかったときに表示するために初めて、点線のルールをしたいと思い、持っていたが、しません

その後、我々は2回目のスキャン、少し考え方を学びました。

 

 

 

 

 物事はそれの形而上学に本当にしていること。

書式#include <iostreamの>
書式#include <CStringの>
書式#include <ベクトル>
書式#include <アルゴリズム>
名前空間stdを使用。
長い長いLLのtypedef。
const int型MAXN = 1E5 + 7。
CONST LL MOD = 1E9 + 7。
構造体ノード{
	int型のp;
	LLのlen;
	ノード(INT _p、LL _len):P(-P)、手段(_len){}
}。
int型のn;
LL DP [MAXN] [5]。
LL CNT [MAXN] [6]。
ベクター<ノード> G [MAXN]。
ボイド挿入(であるINT、INT EN、LL LEN){
	G .push_back(ノード(EN、LEN))です]。
}
DFS2あなたは{(あなたが得る、あなたはFA)
	以下のために(INT I 0 =; I <G [X] .size(); iが++){
		INT P = G [X] [I] .P。
		LL LEN = G [X] [I] .LEN。
		継続した(p == FA)であれば、
		DFS2(P、x)は、
		{ため(++; <3 = 0の整数)
			DP [X] [(A + LEN)%3] + =(DP [P] [A] + CNT [P] [A] * LEN)%MOD。
			CNT [X] [(A + LEN)%3] + = CNT [P] [A]。
			DP [X] [(A + LEN)%3]%= MOD。
		}
		DP [X] [わずか3%] + =のみ。
		dp[x][len % 3] %= mod;
		cnt[x][len % 3] ++;
	}
	return 0;
}
ll ans[10];
ll son[10];
int dfs(int x, int fa) {
	for (int i = 0; i < G[x].size(); i++) {
		int p = G[x][i].p;
		ll len = G[x][i].len;
		if (p == fa) continue;
		
		for (int a = 0; a < 3; a++) {
			ans[(a + len) % 3] = (dp[x][(a + len) % 3] - (cnt[p][a] * len + dp[p][a])) % mod;

			ans[(a + len) % 3] += mod;
			ans[(a + len) % 3] %= mod;
			son[(a + len) % 3] = cnt[x][(a + len) % 3] - cnt[p][a];
		}
		son[len % 3]--;
		ans[len % 3] = (ans[len % 3] - len + mod) % mod;
		
		//删除了多的边
		for (int a = 0; a < 3; a++) {
			dp[p][(a + len) % 3] += (ans[a] + son[a] * len) % mod;
			dp[p][(a + len) % 3] %= mod;
			cnt[p][(a + len) % 3] += son[a];
		}
		cnt[p][len % 3]++;
		dp[p][len % 3] += len;
		dp[p][len % 3] %= mod;

		dfs(p, x);
	}
	return 0;
}
int main() {
	while (~scanf("%d", &n)) {
		for (int i = 0; i <= n; i++) G[i].clear();
		memset(dp, 0, sizeof(dp));
		memset(cnt, 0, sizeof(cnt));
		int be, en;
		ll len;
		for (int i = 1; i < n; i++) {
			scanf("%d %d %lld", &be, &en, &len);
			insert(be, en, len);
			insert(en, be, len);
		}
		dfs2(0, -1);
		dfs(0, -1);
	
		ll a = 0, b = 0, c = 0;
		for (int i = 0; i < n; i++) {
			a = (a + dp[i][0]) % mod;
			b = (b + dp[i][1]) % mod;
			c = (c + dp[i][2]) % mod;
		}
		printf("%lld %lld %lld\n", a, b, c);
	}
	return 0;
}

  

おすすめ

転載: www.cnblogs.com/lesning/p/12120923.html