結果
問題 | No.2360 Path to Integer |
ユーザー | shobonvip |
提出日時 | 2023-06-23 23:49:33 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 392 ms / 2,500 ms |
コード長 | 4,388 bytes |
コンパイル時間 | 5,016 ms |
コンパイル使用メモリ | 280,412 KB |
実行使用メモリ | 22,380 KB |
最終ジャッジ日時 | 2024-07-01 03:37:37 |
合計ジャッジ時間 | 8,761 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 4 ms
5,376 KB |
testcase_08 | AC | 27 ms
5,376 KB |
testcase_09 | AC | 392 ms
19,212 KB |
testcase_10 | AC | 152 ms
22,380 KB |
testcase_11 | AC | 158 ms
22,380 KB |
testcase_12 | AC | 254 ms
19,160 KB |
testcase_13 | AC | 378 ms
19,080 KB |
testcase_14 | AC | 382 ms
19,584 KB |
testcase_15 | AC | 371 ms
19,080 KB |
testcase_16 | AC | 380 ms
19,660 KB |
ソースコード
#include<bits/stdc++.h> #include<atcoder/all> using namespace std; using namespace atcoder; typedef modint998244353 mint; typedef long long ll; pair<int,vector<pair<int,int>>> find_centroid(int st, int size, vector<vector<int>> &ikeru, vector<int> &sizedp, vector<int> &tansaku, vector<bool> &removed){ vector<int> mada = {~st, st}; tansaku[st] = 1; while (!mada.empty()){ int i = mada.back(); mada.pop_back(); if (i >= 0){ for (int j: ikeru[i]){ if (removed[j]) continue; if (tansaku[j] != 1){ tansaku[j] = 1; mada.push_back(~j); mada.push_back(j); } } }else{ i = ~i; int tmp = 1; for (int j: ikeru[i]){ if (removed[j]) continue; if (tansaku[j] == 2) tmp += sizedp[j]; } sizedp[i] = tmp; tansaku[i] = 2; } } int now = st; tansaku[now] = 3; vector<pair<int,int>> ret(0); int par = st; while (true){ int v = 0, w = 0; if (size != sizedp[now]){ ret = {make_pair(par, size-sizedp[now])}; } for (int j: ikeru[now]){ if (removed[j]) continue; if (tansaku[j] == 2){ tansaku[j] = 3; ret.push_back(make_pair(j, sizedp[j])); if (v < sizedp[j]){ v = sizedp[j]; w = j; } } } if (v * 2 <= size) break; par = now; now = w; } removed[now] = true; return make_pair(now, ret); } void solve(int st,\ int size,\ vector<vector<int>> &ikeru,\ vector<int> &sizedp,\ vector<int> &tansaku,\ vector<bool> &removed,\ mint &ans,\ vector<mint> &a,\ vector<int> &asize,\ vector<mint> &beki10){ pair<int,vector<pair<int,int>>> ret = find_centroid(st, size, ikeru, sizedp, tansaku, removed); //vector<mint> goes((int)ret.second.size()); if ((int)ret.second.size() > 0){ vector<mint> come((int)ret.second.size()); vector<mint> goes((int)ret.second.size()); vector<mint> nums((int)ret.second.size()); vector<tuple<int,int,mint>> dp;// KAIWAI, KETA, ATAI (goes) mint comesum = 0; mint goessum = 0; mint numssum = 0; int cnt = 0; for (pair<int,int> i: ret.second){ vector<int> mada = {i.first}; vector<int> sgn = {asize[i.first]}; vector<mint> gotmp = {a[i.first]}; vector<mint> cotmp = {a[i.first]}; tansaku[i.first] = 4; while(!mada.empty()){ //cout << (int)mada.size() << " " << sgn.size() << " " << gotmp.size() << " " << cotmp.size() << endl; int x = mada.back(); mada.pop_back(); numssum++; nums[cnt]++; int xsgn = sgn.back(); sgn.pop_back(); goes[cnt] += gotmp.back(); //goessum += gotmp.back(); mint nowgo = gotmp.back(); goessum += nowgo; gotmp.pop_back(); come[cnt] += cotmp.back(); mint nowco = cotmp.back(); comesum += nowco; cotmp.pop_back(); ans += nowgo + beki10[xsgn] * a[ret.first]; ans += nowco * beki10[asize[ret.first]] + a[ret.first]; dp.push_back(tuple(cnt, xsgn, nowgo)); for (int j: ikeru[x]){ if (removed[j]) continue; if (tansaku[j] != 4){ tansaku[j] = 4; mada.push_back(j); sgn.push_back(asize[j] + xsgn); gotmp.push_back(nowgo * beki10[asize[j]] + a[j]); cotmp.push_back(nowco + a[j] * beki10[xsgn]); } } } cnt++; } for (auto [kaiwai, keta, atai]: dp){ //cout << atai.val() << " " << keta << endl; ans += (atai + beki10[keta] * a[ret.first]) * (numssum - nums[kaiwai]) + beki10[keta + asize[ret.first]] * (comesum - come[kaiwai]); } } for (pair<int,int> i: ret.second){ solve(i.first, i.second, ikeru, sizedp, tansaku, removed, ans, a, asize, beki10); } } int main(){ int n; cin >> n; vector<string> as(n); for (int i=0; i<n; i++){ cin >> as[i]; } vector<int> asize(n); for (int i=0; i<n; i++){ asize[i] = as[i].size(); } vector<mint> a(n); for (int i=0; i<n; i++){ //reverse(as[i].begin(), as[i].end()); for (int j=0; j<(int)as[i].size(); j++){ a[i] = a[i] * 10 + (as[i][j] - '0'); } } vector<vector<int>> ikeru(n, vector<int>(0)); vector<int> sizedp(n); vector<int> tansaku(n); vector<bool> removed(n); for (int i=0; i<n-1; i++){ int a, b; cin >> a >> b; a--; b--; ikeru[a].push_back(b); ikeru[b].push_back(a); } mint ans = 0; for (int i=0; i<n; i++){ ans += a[i]; } vector<mint> beki10(10*n+1); beki10[0] = 1; for (int i=1; i<=10*n; i++){ beki10[i] = beki10[i-1] * mint(10); } solve(0, n, ikeru, sizedp, tansaku, removed, ans, a, asize, beki10); cout << ans.val() << endl; }