Submission #58813

#TimeUsernameProblemLanguageResultExecution timeMemory
58813BenqHard route (IZhO17_road)C++14
100 / 100
1537 ms255532 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> using namespace std; using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef complex<ld> cd; typedef pair<int, int> pi; typedef pair<ll,ll> pl; typedef pair<ld,ld> pd; typedef vector<int> vi; typedef vector<ld> vd; typedef vector<ll> vl; typedef vector<pi> vpi; typedef vector<pl> vpl; typedef vector<cd> vcd; template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; #define FOR(i, a, b) for (int i=a; i<(b); i++) #define F0R(i, a) for (int i=0; i<(a); i++) #define FORd(i,a,b) for (int i = (b)-1; i >= a; i--) #define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--) #define sz(x) (int)(x).size() #define mp make_pair #define pb push_back #define f first #define s second #define lb lower_bound #define ub upper_bound #define all(x) x.begin(), x.end() const int MOD = 1000000007; const ll INF = 1e18; const int MX = 500001; int n, dist[MX], pre[MX], besDist[MX]; vi adj[MX]; pl bes = {-1,0}; void tri(pl x) { if (x.f > bes.f) bes = {x.f,0}; if (x.f == bes.f) bes.s += x.s; } void dfs(int cur) { for (int i: adj[cur]) if (i != pre[cur]) { pre[i] = cur; dist[i] = dist[cur]+1; dfs(i); } } void genDist(int cur) { memset(dist,0,sizeof dist); pre[cur] = -1; dfs(cur); } int treeDiameter() { genDist(1); int bes = 0; FOR(i,1,n+1) if (dist[i] > dist[bes]) bes = i; genDist(bes); FOR(i,1,n+1) if (dist[i] > dist[bes]) bes = i; return dist[bes]; } int t; vi x; vi genCenter() { t = treeDiameter(); int bes = 0; FOR(i,1,n+1) if (dist[i] > dist[bes]) bes = i; F0R(i,t/2) bes = pre[bes]; if (t&1) return {bes,pre[bes]}; return {bes}; } pi dfs(int a, int b, int c) { vpi v; pi z = {0,0}; for (int i: adj[a]) if (i != b) { pi t = dfs(i,a,c+1); t.f ++; v.pb(t); if (t.f > z.f) z.s = z.f, z.f = t.f; else if (t.f > z.s) z.s = t.f; } int co = 0; for (int i: adj[a]) if (i != b) { if (v[co].f == z.f) besDist[i] = z.s; else besDist[i] = z.f; co ++; } if (sz(v) == 0) v.pb({0,1}); if (sz(v) == 1) return v[0]; sort(v.rbegin(),v.rend()); int ind = 0, sum = v[0].s; while (ind+1 < sz(v) && v[ind+1].f == v[ind].f) sum += v[++ind].s; if (ind > 0) { ll t = (ll)sum*(sum-1)/2; F0R(i,ind+1) t -= (ll)v[i].s*(v[i].s-1)/2; tri({(ll)v[0].f*2*c,t}); } else { ll sum2 = 0; int ind = 1; while (ind < sz(v) && v[ind].f == v[1].f) sum2 += v[ind++].s; tri({(ll)(v[0].f+v[1].f)*c,(ll)sum2*sum}); } return {v[0].f,sum}; } vpi tmp; void solveNoCenter() { if (sz(x) == 2) { tmp.pb(dfs(x[1],x[0],t/2+1)); tmp.pb(dfs(x[0],x[1],t/2+1)); } else { for (int i: adj[x[0]]) tmp.pb(dfs(i,x[0],t/2+1)); } } vpi z[2]; void dfs2(int cur, int pre, int cdist, int cmx, int ind) { bool isLeaf = 1; for (int i: adj[cur]) if (i != pre) { dfs2(i,cur,cdist+1,max(cmx,besDist[i]),ind); isLeaf = 0; } if (isLeaf) z[ind].pb({cmx,cdist}); } int stor[2][500001]; void solveCenter() { vi maj; ll sum = 0, bad = 0; int mx = 0; if (sz(x) == 2) maj = x; else { F0R(i,sz(tmp)) if (tmp[i].f == t/2-1) { maj.pb(adj[x[0]][i]); sum += tmp[i].s; bad += (ll)tmp[i].s*(tmp[i].s-1)/2; } else { mx = max(mx,tmp[i].f+1); } } if (sz(maj) > 2) { tri({(ll)t*t/2,(ll)sum*(sum-1)/2-bad}); return; } // cout << "OH " << sz(x) << " " << maj[0] << " " << maj[1] << "\n"; //cout << sz(maj) << " " << x[0] << "\n"; //exit(0); //cout << maj[0] << " " << maj[1] << " " << x[0] << " " << mx << "\n"; if (sz(x) == 2) { dfs2(x[0],x[1],0,0,0); dfs2(x[1],x[0],1,0,1); } else { dfs2(maj[0],x[0],1,mx,0); dfs2(maj[1],x[0],1,mx,1); } sort(all(z[0])), sort(all(z[1])); F0R(k,2) for (auto a: z[k]) stor[k][a.s] ++; array<int,2> t = {500000,500000}; while (sz(z[0]) && sz(z[1])) { F0R(k,2) while (!stor[k][t[k]]) t[k] --; if (z[0].back().f < z[1].back().f) { tri({(ll)(t[0]+z[1].back().s)*z[1].back().f,stor[0][t[0]]}); stor[1][z[1].back().s] --; z[1].pop_back(); } else { tri({(ll)(t[1]+z[0].back().s)*z[0].back().f,stor[1][t[1]]}); stor[0][z[0].back().s] --; z[0].pop_back(); } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; F0R(i,n-1) { int a, b; cin >> a >> b; adj[a].pb(b), adj[b].pb(a); } x = genCenter(); solveNoCenter(); // cout << bes.f << " " << bes.s << "\n"; solveCenter(); cout << bes.f << " " << bes.s; } /* Look for: * the exact constraints (multiple sets are too slow for n=10^6 :( ) * special cases (n=1?) * overflow (ll vs int?) * array bounds */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...