結果

問題 No.1418 Sum of Sum of Subtree Size
ユーザー kwm_tkwm_t
提出日時 2021-03-07 18:57:08
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 162 ms / 2,000 ms
コード長 2,857 bytes
コンパイル時間 2,955 ms
コンパイル使用メモリ 184,780 KB
実行使用メモリ 49,664 KB
最終ジャッジ日時 2024-10-09 02:07:28
合計ジャッジ時間 6,628 ms
ジャッジサーバーID
(参考情報)
judge4 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 1 ms
5,248 KB
testcase_03 AC 162 ms
15,884 KB
testcase_04 AC 134 ms
16,000 KB
testcase_05 AC 137 ms
15,872 KB
testcase_06 AC 136 ms
15,872 KB
testcase_07 AC 131 ms
15,872 KB
testcase_08 AC 80 ms
11,776 KB
testcase_09 AC 34 ms
7,296 KB
testcase_10 AC 36 ms
7,680 KB
testcase_11 AC 19 ms
5,632 KB
testcase_12 AC 57 ms
9,984 KB
testcase_13 AC 67 ms
11,264 KB
testcase_14 AC 75 ms
11,648 KB
testcase_15 AC 52 ms
9,600 KB
testcase_16 AC 8 ms
5,248 KB
testcase_17 AC 7 ms
5,248 KB
testcase_18 AC 113 ms
14,720 KB
testcase_19 AC 19 ms
5,376 KB
testcase_20 AC 4 ms
5,248 KB
testcase_21 AC 56 ms
9,344 KB
testcase_22 AC 46 ms
8,448 KB
testcase_23 AC 5 ms
5,248 KB
testcase_24 AC 5 ms
5,248 KB
testcase_25 AC 4 ms
5,248 KB
testcase_26 AC 5 ms
5,248 KB
testcase_27 AC 2 ms
5,248 KB
testcase_28 AC 3 ms
5,248 KB
testcase_29 AC 6 ms
5,248 KB
testcase_30 AC 6 ms
5,248 KB
testcase_31 AC 4 ms
5,248 KB
testcase_32 AC 4 ms
5,248 KB
testcase_33 AC 30 ms
13,696 KB
testcase_34 AC 141 ms
49,664 KB
testcase_35 AC 68 ms
22,784 KB
testcase_36 AC 12 ms
5,248 KB
testcase_37 AC 91 ms
16,736 KB
testcase_38 AC 82 ms
15,788 KB
testcase_39 AC 2 ms
5,248 KB
testcase_40 AC 2 ms
5,248 KB
testcase_41 AC 2 ms
5,248 KB
testcase_42 AC 2 ms
5,248 KB
testcase_43 AC 2 ms
5,248 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include "bits/stdc++.h"
//#include "atcoder/all"
using namespace std;
//using namespace atcoder;
//using mint = modint1000000007;
//const int mod = 1000000007;
//using mint = modint998244353;
//const int mod = 998244353;
//const int INF = 1e9;
//const long long LINF = 1e18;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep2(i,l,r)for(int i=(l);i<(r);++i)
#define rrep(i, n) for (int i = (n-1); i >= 0; --i)
#define rrep2(i,l,r)for(int i=(r-1);i>=(l);--i)
#define all(x) (x).begin(),(x).end()
#define allR(x) (x).rbegin(),(x).rend()
#define endl "\n"

using pll = pair<long long, long long>;//自分のサイズ、それ以下のサイズの合計
template <typename T>
struct ReRooting
{
	using F = function<T(T, int)>;
	using F2 = function<T(T, T)>;
	int V;
	vector<vector<int>> G;
	vector<vector<T>> dp;
	// dp_v = g(merge(f(dp_c1,c1), f(dp_c2,c2), ..., f(dp_ck,ck)), v)
	F f, g;
	F2 merge;
	T mi; // identity of merge(マージの単位元)

	ReRooting() {}
	ReRooting(int V, F f, F2 merge, T mi, F g): V(V), f(f), merge(merge), mi(mi), g(g){
		G.resize(V);
		dp.resize(V);
	}

	void read_graph(int index = 1){
		int a, b;
		for (int i = 0; i < V - 1; ++i){
			cin >> a >> b;
			a -= index, b -= index;
			G[a].emplace_back(b);
			G[b].emplace_back(a);
		}
	}

	void add_edge(int a, int b){
		G[a].emplace_back(b);
		G[b].emplace_back(a);
	}

	T dfs1(int p, int v){
		T res = mi;
		for (int i = 0; i < G[v].size(); ++i){
			if (G[v][i] == p) {continue;}
			dp[v][i] = dfs1(v, G[v][i]);
			res = merge(res, f(dp[v][i], G[v][i]));
		}
		return g(res, v);
	}

	void dfs2(int p, int v, T from_par){
		for (int i = 0; i < G[v].size(); ++i){
			if (G[v][i] == p){
				dp[v][i] = from_par;
				break;
			}
		}
		vector<T> pR(G[v].size() + 1);//pR[i] = [i,G[v].size())
		pR[G[v].size()] = mi;
		for (int i = G[v].size(); i > 0; --i) {
			pR[i - 1] = merge(pR[i], f(dp[v][i - 1], G[v][i - 1]));
		}
		T pL = mi;
		for (int i = 0; i < G[v].size(); ++i){
			if (G[v][i] != p){
				T val = merge(pL, pR[i + 1]);//pL:=[0,i)
				dfs2(v, G[v][i], g(val, v));
			}
			pL = merge(pL, f(dp[v][i], G[v][i]));
		}
	}

	void calc(int root = 0){
		for (int i = 0; i < V; ++i) { dp[i].resize(G[i].size()); }
		dfs1(-1, root);
		dfs2(-1, root, mi);
	}

	T solve(int v){
		T ans = mi;
		for (int i = 0; i < G[v].size(); ++i) {
			ans = merge(ans, f(dp[v][i], G[v][i]));
		}
		return g(ans, v);
	}
};

int main(){
	int N;
	cin >> N;
	//★↓編集
	auto f = [](pll p, int temp) { return p; };
	auto merge = [](pll p, pll q) { return pll{ p.first + q.first, p.second + q.second }; };
	auto g = [](pll p, int temp) { return pll{ p.first + 1, p.second + p.first + 1 }; };
	pll midx = { 0,0 };
	//★↑編集
	ReRooting<pll> re(N, f, merge, midx, g);
	re.read_graph();
	re.calc();
	long long sum = 0;
	rep(i, N) {
		sum += re.solve(i).second;
	}
	cout << sum << endl;
}
0