結果
| 問題 |
No.3350 Tree and Two Apples
|
| コンテスト | |
| ユーザー |
Cafe1942
|
| 提出日時 | 2025-11-13 23:26:27 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,653 bytes |
| コンパイル時間 | 1,517 ms |
| コンパイル使用メモリ | 125,328 KB |
| 実行使用メモリ | 14,824 KB |
| 最終ジャッジ日時 | 2025-11-13 23:26:35 |
| 合計ジャッジ時間 | 6,905 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 4 WA * 31 |
ソースコード
#include <iostream>
#include <iomanip>//小数点出力用
//cout << fixed << setprecision(10) << ans;
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <unordered_map>
using ll = long long;
using namespace std;
#define modPHash (ll)((1LL<<61)-1)
#define modP (ll)998244353
bool chkrng0idx(int pos, int sup) { return (0 <= pos && pos < sup); }
int clk4(int num) { return (num - 2) * (num % 2); }
void yn(bool tf) { cout << (tf ? "YES\n" : "NO\n"); }
vector<int> nxt[200002];//行先,距離
vector<int> centroid_cand;
int search_center(int now, int parent, int size) {//与えられた部分木内の重心を見つける 変更非推奨
int res = 1;
bool ok = 1;
for (int j = 0;j < nxt[now].size();j++) {
if (parent != nxt[now][j]) {
auto X = search_center(nxt[now][j], now, size);
if (X > size / 2) {
ok = 0;
}
res += X;
}
}
if (size - res > size / 2) {
ok = 0;
}
if (ok) {
centroid_cand.push_back(now);
}
return res;
}
ll mul(ll X, ll Y) {
ll res = 0;
for (int k = 62;k >= 0;k--) {
res <<= 1;
res %= modPHash;
if ((Y >> k) & 1) {
res += X;
res %= modPHash;
}
}
return res;
}
ll getHash(int now, int parent) {
vector<ll>kid;
kid.reserve(nxt[now].size());
ll res = 123456789;
ll T = 1;
for (int j = 0;j < nxt[now].size();j++) {
if (parent != nxt[now][j]) {
kid.push_back(getHash(nxt[now][j], now));
}
}
sort(kid.begin(), kid.end());
for (int j = 0;j < kid.size();j++) {
res += mul(T, kid[j]);
res %= modPHash;
}
return res;
}
ll kidCnt[100001];
ll underPair[100001];
ll underKind[100001];
ll dfs(int now, int parent) {
vector<pair<ll, int>>kid;
kid.reserve(nxt[now].size());
ll res = 123456789;
ll T = 1;
for (int j = 0;j < nxt[now].size();j++) {
if (parent != nxt[now][j]) {
kid.push_back({ dfs(nxt[now][j], now), nxt[now][j] });
}
}
sort(kid.begin(), kid.end());
ll combo = 0;
ll nowH = 0;
int k = 0;
underKind[now] = 1;
underPair[now] = 1;
ll backKind = 0;
for (int j = 0;j < kid.size();j++) {
res += mul(T, kid[j].first);
res %= modPHash;
if (nowH == kid[j].first) {
combo++;
}
else {
if (combo >= 2) {
underPair[now] += underPair[k];
underPair[now] += 2LL * underKind[k];
underPair[now] += underKind[k] * underKind[k];
underKind[now] += underKind[k];
underPair[now] += backKind * underKind[k] * 2LL;
backKind += underKind[k];
}
if (combo == 1) {
underPair[now] += underPair[k];
underPair[now] += 2LL * underKind[k];
underKind[now] += underKind[k];
underPair[now] += backKind * underKind[k] * 2LL;
backKind += underKind[k];
}
combo = 1;
nowH = kid[j].first;
k = kid[j].second;
}
T *= 3LL;
T %= modPHash;
}
if (combo >= 2) {
underPair[now] += underPair[k];
underPair[now] += 2LL * underKind[k];
underPair[now] += underKind[k] * underKind[k];
underKind[now] += underKind[k];
underPair[now] += backKind * underKind[k] * 2LL;
}
if (combo == 1) {
underPair[now] += underPair[k];
underPair[now] += 2LL * underKind[k];
underKind[now] += underKind[k];
underPair[now] += backKind * underKind[k] * 2LL;
}
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
for (int i = 1;i < N;i++) {
int U, V;
cin >> U >> V;
nxt[U].push_back(V);
nxt[V].push_back(U);
}
if (N == 1) {
cout << 1;
return 0;
}
if (N == 2) {
cout << 2;
return 0;
}
if (N == 3) {
cout << 5;
return 0;
}
search_center(1, -1, N);
if (centroid_cand.size() == 2 && getHash(centroid_cand[0], centroid_cand[1]) == getHash(centroid_cand[1], centroid_cand[0])) {
dfs(centroid_cand[0], centroid_cand[1]);
cout << underPair[centroid_cand[0]] + underKind[centroid_cand[0]] * underKind[centroid_cand[0]];
}
else {
dfs(centroid_cand[0], -1);
cout << underPair[centroid_cand[0]];
}
return 0;
}
Cafe1942