冒着滥用此题将封号的风险测了七发RP才过……
每个点建两个双堆,堆a表示这个点所在的子树里所有点到他点分树中父亲的距离,堆b表示所有点分树子树中到他距离最大的个点的距离,堆c用来存全局答案,显然全局答案就是每个堆b中最大值和次大值的和
点分树上暴跳父亲复杂度是log的,所以总复杂度是 n l o g 2 n nlog^2n nlog2n
代码如下:
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int X=0,w=0; char ch=0;
while(!isdigit(ch)) {
w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
struct heap
{
priority_queue<int> q1,q2;
void insert(int val)
{
q1.push(val);
}
void erase(int val)
{
q2.push(val);
}
int top()
{
while(q2.size()&&q1.top()==q2.top()) q1.pop(),q2.pop();
return q1.top();
}
void pop()
{
while(q2.size()&&q1.top()==q2.top()) q1.pop(),q2.pop();
if(q1.size()) q1.pop();
}
int top2()
{
int val=top();pop();
int res=top();insert(val);
return res;
}
int size()
{
return q1.size()-q2.size();
}
}a[100010],b[100010],c;
int sz[100010],deep[100010];
int fa[100010],f[100010],fu[