結果

問題 No.2360 Path to Integer
ユーザー aoblue2547aoblue2547
提出日時 2024-02-26 00:10:12
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 152 ms / 2,500 ms
コード長 3,845 bytes
コンパイル時間 5,908 ms
コンパイル使用メモリ 320,276 KB
実行使用メモリ 38,272 KB
最終ジャッジ日時 2024-02-26 00:10:21
合計ジャッジ時間 8,868 ms
ジャッジサーバーID
(参考情報)
judge11 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,676 KB
testcase_01 AC 2 ms
6,676 KB
testcase_02 AC 2 ms
6,676 KB
testcase_03 AC 2 ms
6,676 KB
testcase_04 AC 2 ms
6,676 KB
testcase_05 AC 2 ms
6,676 KB
testcase_06 AC 2 ms
6,676 KB
testcase_07 AC 2 ms
6,676 KB
testcase_08 AC 11 ms
6,676 KB
testcase_09 AC 152 ms
17,920 KB
testcase_10 AC 119 ms
18,588 KB
testcase_11 AC 135 ms
18,588 KB
testcase_12 AC 79 ms
18,176 KB
testcase_13 AC 146 ms
17,920 KB
testcase_14 AC 141 ms
34,432 KB
testcase_15 AC 145 ms
17,920 KB
testcase_16 AC 152 ms
38,272 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

//テンプレート
//Visual Studio用
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
template<class T> bool chmin(T& a, T b) { return a > b ? a = b, true : false; }
template<class T> bool chmax(T& a, T b) { return a < b ? a = b, true : false; }
template<class T>istream& operator>>(istream& is, vector<T>& v) { for (auto& e : v)is >> e; return is; }
template<class T>ostream& operator<<(ostream& os, vector<T>& v) { for (auto& e : v)os << e << " "; return os; }
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
template<class T = ll> struct Edge {
	int to;
	T weight;
	Edge(int t, T w) :to(t), weight(w) {}
	bool operator==(Edge e) {
		return this->to == e.to and this->weight == e.weight;
	}
	bool operator<(Edge e) {
		if (this->to < e.to) {
			return this->weight <= e.weight;
		}
		else return false;
	}
};
template<class T = ll> class Graph {
	using graph_ = vector<vector<Edge<T>>>;
	graph_ g;
public:
	Graph(int n) :g(n) {}
	graph_::iterator begin() { return g.begin(); }
	graph_::const_iterator begin() const { return g.begin(); }
	graph_::iterator end() { return g.end(); }
	graph_::const_iterator end() const { return g.end(); }
	vector<Edge<T>>& operator [](int v) {
		return g[v];
	}
	const graph_& data() { return g; }
	void add(int u, int v, T w = 1) {
		g[u].emplace_back(Edge<T>{ v, w });
	}
	void wadd(int u, int v, T w = 1) {
		add(u, v, w);
		add(v, u, w);
	}
	void add(int u, Edge<T> edge) {
		g[u].emplace_back(edge);
	}
};

//Atcoder Library
/**/
#include <atcoder/all>
using namespace atcoder;
using mint = modint998244353;
//using mint = modint1000000007;
//using mint = dynamic_modint<0>;
//using mint = modint;
//mint::set_mod();
istream& operator>>(istream& is, mint& x) { ll r; cin >> r; x = r; return is; }
ostream& operator<<(ostream& os, mint& x) { cout << x.val(); return os; }
/**/
#define SHOW(n) cerr << #n << " = " << n << endl;

/*
ここまでテンプレート
*/




int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	int n;
	cin >> n;
	vector<mint> a(n, 0);
	vector<int> siz(n);
	for (int i = 0; i < n; ++i) {
		string s;
		cin >> s;

		siz[i] = s.size();
		for (int j = 0; j < s.size(); ++j) {
			if (j != 0) a[i] *= 10;
			a[i] += s[j] - '0';
		}
	}

	Graph g(n);
	for (int i = 0; i < n - 1; ++i) {
		int a, b;
		cin >> a >> b;
		--a; --b;
		g.wadd(a, b);
	}

	vector<mint> dp(n, 0);
	vector<vector<mint>> dp_aux(n);
	vector<int> bubun(n, 0);

	auto dfs1 = [&](auto&& f, int v, int prev)->mint {

		mint res = 0;
		const int deg = g[v].size();
		dp_aux[v].resize(deg);



		for (int i = 0; i < deg; ++i) {
			int s = g[v][i].to;
			if (s == prev)continue;
			f(f, s, v);
			dp_aux[v][i] = dp[s];
			res = res + dp_aux[v][i];

			bubun[v] += bubun[s];
		}

		bubun[v] += 1;

		res *= mint(10).pow(siz[v]);
		res += a[v] * (bubun[v]);

		
		return dp[v] = res;

		};

	dfs1(dfs1, 0, -1);


	auto dfs2 = [&](auto&& f, int v, int prev, mint pval, int subsiz)->void {

		const int deg = g[v].size();
		for (int i = 0; i < deg; ++i) {
			if (g[v][i].to == prev)dp_aux[v][i] = pval;
		}

		// 左右からdp_aux[v][i]の累積和を取る
		vector<mint> accl(deg + 1, 0), accr(deg + 1, 0);
		for (int i = 0; i < deg; ++i) {
			accl[i + 1] = accl[i] + dp_aux[v][i];
		}
		for (int i = deg - 1; i >= 0; --i) {
			accr[i] = accr[i + 1] + dp_aux[v][i];
		}

		dp[v] = accl[deg];


		dp[v] *= mint(10).pow(siz[v]);
		dp[v] += a[v] * (subsiz + bubun[v]);

		// 行きがけ順で探索する
		for (int i = 0; i < deg; ++i) {
			int s = g[v][i].to;
			if (s == prev)continue;
			mint val = accl[i] + accr[i + 1];
			val *= mint(10).pow(siz[v]);
			val += a[v] * (n - bubun[s]);
			f(f, s, v, val, n - bubun[s]);
		}

		};

	dfs2(dfs2, 0, -1, 0, 0);


	mint res = reduce(dp.begin(), dp.end());

	cout << res.val() << endl;



	return 0;
}
0