結果
| 問題 |
No.439 チワワのなる木
|
| コンテスト | |
| ユーザー |
🍡yurahuna
|
| 提出日時 | 2016-10-26 19:34:37 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 68 ms / 5,000 ms |
| コード長 | 2,610 bytes |
| コンパイル時間 | 1,619 ms |
| コンパイル使用メモリ | 171,928 KB |
| 実行使用メモリ | 18,048 KB |
| 最終ジャッジ日時 | 2024-11-24 03:54:10 |
| 合計ジャッジ時間 | 3,511 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 28 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i=0;i<(n);i++)
#define rep2(i,a,b) for (int i=(a);i<(b);i++)
#define rrep(i,n) for (int i=(n)-1;i>=0;i--)
#define rrep2(i,a,b) for (int i=(b)-1;i>=(a);i--)
#define all(a) (a).begin(),(a).end()
typedef long long ll;
typedef pair<int, int> P;
// O(N)解
// 2回DFSする
struct Chiwawa {
ll w, ww;
Chiwawa() { w = 0ll, ww = 0ll; }
};
const int MAX_N = 100000;
int N;
string s;
vector<vector<int>> G;
Chiwawa cww[MAX_N]; // 各頂点を根とした部分木に含まれる(w, ww)の個数 (一番上の親は0)
// 配列cwwを用意するためのdfs
Chiwawa dfs(int now, int pre) {
Chiwawa ret;
for (auto nxt : G[now]) {
if (nxt == pre) continue;
auto child = dfs(nxt, now);
ret.w += child.w;
ret.ww += child.ww;
}
if (s[now] == 'w') {
// 自分がwなら、子のwの数だけwwが増える
ret.ww += ret.w;
// wは1増える
++ret.w;
}
cww[now] = ret;
return ret;
}
ll ans; // 答えの記録用
// 答えを求めるdfs
// p: vの部分木に含まれない(w, ww)の個数
void dfs2(int v, int pre, Chiwawa p) {
// この頂点がcなら、つなげられるwwの個数を答えに加える
if (s[v] == 'c') {
ans += p.ww; // pのwwとつなげたとき
for (auto ch : G[v]) {
if (ch == pre) continue;
ans += cww[ch].ww; // chの部分木のwwとつなげたとき
}
}
for (auto ch : G[v]) {
if (ch == pre) continue;
// 次の子に渡すためにpを更新する
auto tmp = p;
// vの部分木のうち、chの部分木の分を除く
tmp.w += cww[v].w, tmp.ww += cww[v].ww;
tmp.w -= cww[ch].w, tmp.ww -= cww[ch].ww;
if (s[v] == 'w') {
// vが 'w' の場合は、 vの 'w' を使っている分のwwの個数が変化する
// v の 'w' と chの部分木の 'w' を使っている ww は減る
tmp.ww -= cww[ch].w;
// v の 'w' と p の 'w' を使っている ww が増える
tmp.ww += p.w;
}
// 子に移動
dfs2(ch, v, tmp);
}
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
cin >> N;
cin >> s;
G.resize(N);
rep(i, N - 1) {
int a, b;
cin >> a >> b;
a--; b--;
G[a].emplace_back(b);
G[b].emplace_back(a);
}
// 準備
dfs(0, -1);
// 本番
dfs2(0, -1, Chiwawa());
cout << ans << endl;
}
🍡yurahuna