This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
struct MaxCount {
int length;
long long ways;
MaxCount(): length(0), ways(0) {}
MaxCount(int length, long long ways):length(length), ways(ways) {}
MaxCount(pair<int, long long> it): length(it.first), ways(it.second) {}
bool operator<(const MaxCount& that) const { return this -> length < that.length; }
void merge(const MaxCount& that) {
if (this -> length == that.length) {
this->ways += that.ways;
}
if (this->length < that.length) *this = that;
}
MaxCount operator* (const MaxCount &that) {
return {this->length * that.length, this->ways};
}
MaxCount& operator+=(const MaxCount &that) {
this->length += that.length;
this->ways *= that.ways;
return *this;
}
MaxCount operator+(MaxCount that) {
that += *this;
return that;
}
};
std::ostream& operator<<(std::ostream& os, const MaxCount& f) {
return os << ": Length: " << f.length << ", Ways: " << f.ways << '\n';
}
const int N = 5e5 + 100;
int n, leaf;
vector<int> e[N];
MaxCount f1[N], f2[N];
map<int, long long> total[N];
// vector<MaxCount> longest[N];
MaxCount dfsDown(int u, int p) {
// f[u] = MaxCount(0, 1);
total[u][0] = 1;
for (int v : e[u]) if (v != p) {
MaxCount curr = dfsDown(v, u) + MaxCount(1, 1);
// longest[u].push_back(curr);
total[u][curr.length] += curr.ways;
}
// if (total[u].size() == 1) ++leaf;
// sort(longest[u].begin(), longest[u].end());
// reverse(longest[u].begin(), longest[u].end());
// cerr << "At " << u << '\n';
// cerr << "All \n";
// for (auto l : longest[u]) cerr << l;
// cerr << "Longest:" << MaxCount(*total[u].rbegin());
return MaxCount(*total[u].rbegin());
}
MaxCount best(0, 1);
void dfsUp(int u, int p, MaxCount outOfSubtree) {
// cerr << "Up at " << u << outOfSubtree;
vector<MaxCount> pref1(e[u].size()), pref2(e[u].size()), suff1(e[u].size()), suff2(e[u].size()), f(e[u].size());
// cerr << "F + Pref\n";
for (int i = 0; i < e[u].size(); ++i) {
int v = e[u][i];
if (v != p) f[i] = MaxCount(*total[v].rbegin()) + MaxCount(1, 1);
else f[i] = outOfSubtree;
pref1[i] = f[i];
if (i) {
pref1[i].merge(pref1[i - 1]);
pref2[i] = pref2[i - 1];
pref2[i].merge(pref1[i - 1] + f[i]);
}
// cerr << i << ' ' << v << ' ' << f[i] << ' ' << pref1[i] << ' ' << pref2[i] << '\n';
}
// cerr << "Suff\n";
for (int i = e[u].size() - 1; i >= 0; --i) {
int v = e[u][i];
suff1[i] = f[i];
if (i + 1 < e[u].size()) {
suff1[i].merge(suff1[i + 1]);
suff2[i] = suff2[i + 1];
suff2[i].merge(suff1[i + 1] + f[i]);
}
// cerr << i << ' ' << v << ' ' << suff1[i] << ' ' << suff2[i] << '\n';
}
for (int i = 0; i < e[u].size(); ++i) {
int v = e[u][i];
MaxCount curr;
// (pref1, suff1) * v
if (i && i + 1 < e[u].size()) {
curr = (pref1[i - 1] + suff1[i + 1]) * f[i];
// cerr << i << ' ' << v << ' ' << pref1[i - 1] << ' ' << suff1[i + 1] << ' ' << f[i] << ' ' << curr << '\n';
best.merge(curr);
}
// (pref2) * v
if (i > 1) {
curr = (pref2[i - 1]) * f[i];
// cerr << i << ' ' << v << ' ' << pref2[i - 1] << ' ' << f[i] << ' ' << curr << '\n';
best.merge(curr);
}
// (suff2) * v
if (i + 2 < e[u].size()) {
curr = (suff2[i + 1]) * f[i];
// cerr << i << ' ' << v << ' ' << suff2[i + 1] << ' ' << f[i] << ' ' << curr << '\n';
best.merge(curr);
}
}
for (int v : e[u]) if (v != p) {
MaxCount curr(*total[v].rbegin());
total[u][curr.length + 1] -= curr.ways;
if (total[u][curr.length + 1] == 0) total[u].erase(curr.length + 1);
MaxCount thisOutOfSubtree(outOfSubtree);
thisOutOfSubtree.merge(MaxCount(*total[u].rbegin()));
dfsUp(v, u, thisOutOfSubtree + MaxCount(1, 1));
total[u][curr.length + 1] += curr.ways;
}
}
int main() {
ios::sync_with_stdio(false); cin.tie(NULL);
cin >> n;
for (int i = 1; i < n; ++i) {
int u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
dfsDown(1, -1);
dfsUp(1, -1, {-N, 0});
cout << best.length << ' ' << best.ways << '\n';
}
Compilation message (stderr)
road.cpp: In function 'void dfsUp(int, int, MaxCount)':
road.cpp:73:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
73 | for (int i = 0; i < e[u].size(); ++i) {
| ~~^~~~~~~~~~~~~
road.cpp:89:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
89 | if (i + 1 < e[u].size()) {
| ~~~~~~^~~~~~~~~~~~~
road.cpp:87:13: warning: unused variable 'v' [-Wunused-variable]
87 | int v = e[u][i];
| ^
road.cpp:97:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
97 | for (int i = 0; i < e[u].size(); ++i) {
| ~~^~~~~~~~~~~~~
road.cpp:101:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
101 | if (i && i + 1 < e[u].size()) {
| ~~~~~~^~~~~~~~~~~~~
road.cpp:113:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
113 | if (i + 2 < e[u].size()) {
| ~~~~~~^~~~~~~~~~~~~
road.cpp:98:13: warning: unused variable 'v' [-Wunused-variable]
98 | int v = e[u][i];
| ^
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |