#include<bits/stdc++.h>
#pragma GCC optimize("O3,unroll-loops")
using namespace std;
int n;
vector<int> con[500005];
map<int,pair<int,pair<int,int>>> dp[500005];
int root;
int depth[500005];
int siz[500005];
int maxd[500005];
int sus[500005];
int parent[500005];
pair<int,int> mxm = {0,0};
pair<int,pair<int,int>> combine(pair<int,pair<int,int>> x, pair<int,pair<int,int>> y)
{
if(x.second.second==0)
return y;
if(y.second.second==0)
return x;
if(x.first > y.first)
return x;
if(x.first < y.first)
return y;
return {x.first, {x.second.first + y.second.first, x.second.second + y.second.second}};
}
void add_mxm_brut(int nod, set<pair<int,int>> s)
{
for(auto adj:con[nod])
{
if(adj==parent[nod])
continue;
for(auto adj2:con[nod])
{
if(adj2==parent[nod] || adj>=adj2)
continue;
s.erase({maxd[adj],adj});
s.erase({maxd[adj2],adj2});
for(auto it:dp[adj])
{
for(auto it2:dp[adj2])
{
pair<int,int> idk = *s.rbegin();
///pair<int,int> aux = {(it.first + it2.first - 2*depth[nod]) * max({it.second.first,it2.second.first,sus[nod],idk.first-depth[nod]}), it.second.second * it2.second.second};
int moduri;
if(max(sus[nod],idk.first-depth[nod]) == max({it.second.first,it2.second.first,sus[nod],idk.first-depth[nod]}))
{
moduri = it.second.second.second * it2.second.second.second;
}
else if(it.second.first > it2.second.first)
{
moduri = it.second.second.first * it2.second.second.second;
}
else if(it.second.first < it2.second.first)
{
moduri = it2.second.second.first * it.second.second.second;
}
else
{
moduri = it.second.second.first * it2.second.second.second + it2.second.second.first * it.second.second.second - it.second.second.first * it2.second.second.first;
}
pair<int,int> aux = {(it.first + it2.first - 2*depth[nod]) * max({it.second.first,it2.second.first,sus[nod],idk.first-depth[nod]}), moduri};
if(aux.first > mxm.first)
mxm = aux;
else if(aux.first == mxm.first)
mxm.second += aux.second;
}
}
s.insert({maxd[adj],adj});
s.insert({maxd[adj2],adj2});
}
}
}
void add_mxm_fast(int nod, set<pair<int,int>> s)
{
map<int,pair<int,pair<int,int>>> best;
int maxpref=-1;
for(int i=0;i<con[nod].size();i++)
{
int adj = con[nod][i];
if(adj==parent[nod])
continue;
int idk=depth[nod];
for(int j=(int)con[nod].size()-1;j>i;j--)
idk = max(idk, maxd[con[nod][j]]);
//cerr<<nod<<" "<<i<<" "<<con[nod][i]<<" "<<idk<<" idk\n";
for(auto it:dp[adj])
{
for(auto it2:best)
{
int moduri;
if(max(sus[nod],idk-depth[nod]) == max({it.second.first,it2.second.first,sus[nod],idk-depth[nod]}))
{
moduri = it.second.second.second * it2.second.second.second;
}
else if(it.second.first > it2.second.first)
{
moduri = it.second.second.first * it2.second.second.second;
}
else if(it.second.first < it2.second.first)
{
moduri = it2.second.second.first * it.second.second.second;
}
else
{
while(1)
n=0;
moduri = it.second.second.first * it2.second.second.second + it2.second.second.first * it.second.second.second - it.second.second.first * it2.second.second.first;
}
pair<int,int> aux = {(it.first + it2.first - 2*depth[nod]) * max({it.second.first,it2.second.first,sus[nod],idk-depth[nod]}), moduri};
if(aux.first > mxm.first)
mxm = aux;
else if(aux.first == mxm.first)
mxm.second += aux.second;
}
}
for(auto&it:best)
{
if(it.second.first <= maxd[adj])
{
it.second = {maxd[adj],{it.second.second.second,it.second.second.second}};
}
}
for(auto it:dp[adj])
{
pair<int,pair<int,int>> x = it.second;
if(maxpref >= x.first)
x = {maxpref, {x.second.second, x.second.second}};
best[it.first] = combine(best[it.first], x);
}
maxpref = max(maxpref, maxd[adj]);
}
}
void dfs_init(int nod, int par)
{
parent[nod]=par;
siz[nod]=1;
maxd[nod]=depth[nod];
for(auto adj:con[nod])
{
if(adj!=par)
{
depth[adj]=depth[nod]+1;
dfs_init(adj,nod);
maxd[nod] = max(maxd[nod], maxd[adj]);
siz[nod]+=siz[adj];
}
}
}
void dfs(int nod)
{
//cout<<nod<<" start\n";
int cntc=0;
set<pair<int,int>> s;
s.insert({-1,-1});
for(auto adj:con[nod])
{
if(adj!=parent[nod])
{
dfs(adj);
s.insert({maxd[adj], adj});
cntc++;
}
}
//add_mxm_brut(nod,s);
add_mxm_fast(nod,s);
if(cntc==0)
{
dp[nod][depth[nod]] = {0,{1,1}};
}
else
{
for(auto adj:con[nod])
{
if(adj==parent[nod])
continue;
s.erase({maxd[adj],adj});
pair<int,int> idk = *s.rbegin();
//cout<<nod<<" "<<adj<<" "<<idk.first<<" "<<idk.second<<" idk\n";
for(auto it:dp[adj])
{
pair<int,pair<int,int>> x = it.second;
x.first = max(x.first, idk.first - depth[nod]);
if(idk.first - depth[nod] >= x.first)
{
x = {idk.first - depth[nod], {x.second.second, x.second.second}};
}
dp[nod][it.first] = combine(dp[nod][it.first], x);
}
s.insert({maxd[adj],adj});
//dp[adj].clear();
}
}
//for(auto it:dp[nod])
// cout<<nod<<" "<<it.first<<" "<<it.second.first<<" "<<it.second.second<<"\n";
//cout<<nod<<" end\n";
}
void calc_sus()
{
for(int i=1;i<=n;i++)
{
sus[i] = depth[i];
int prec=i;
for(int j=parent[i];j!=0;j=parent[j])
{
for(auto adj:con[j])
{
if(adj!=parent[j] && adj!=prec)
{
sus[i] = max(sus[i], (maxd[adj] - depth[j]) + (depth[i] - depth[j]));
}
}
prec=j;
}
//cout<<i<<" "<<sus[i]<<" sus\n";
}
}
signed main()
{
ios_base::sync_with_stdio(0);cin.tie(0);
cin>>n;
if(n==2)
{
cout<<0<<" "<<1;
return 0;
}
int a,b;
for(int i=1;i<n;i++)
{
cin>>a>>b;
con[a].push_back(b);
con[b].push_back(a);
}
for(int i=n;i>0;i--)
if((int)con[i].size()>1)
root=i;
//cerr<<root<<" is the root\n";
dfs_init(root,0);
calc_sus();
dfs(root);
cout<<mxm.first<<" "<<mxm.second<<"\n";
return 0;
}
/**
7
1 2
1 3
2 4
2 5
4 6
4 7
*/
Compilation message
road.cpp: In function 'void add_mxm_fast(int, std::set<std::pair<int, int> >)':
road.cpp:80:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
80 | for(int i=0;i<con[nod].size();i++)
| ~^~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
2077 ms |
43100 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
2077 ms |
43100 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
2077 ms |
43100 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |