每个点维护一个堆,表示这个点及其子树所需的每段内存的空间
搜索时从下向上做启发式合并堆中信息,最后根节点堆中所有内存空间之和就是答案
#include #define N 200005#define ll long long#define getchar ncusing namespace std;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline int read(){ register int x=0,f=1;register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f;}inline void write(register ll x){ if(!x)putchar('0');if(x<0)x=-x,putchar('-'); static int sta[20];register int tot=0; while(x)sta[tot++]=x%10,x/=10; while(tot)putchar(sta[--tot]+48);}inline int Max(register int a,register int b){ return a>b?a:b;}struct node{ int to,next;}e[N<<1];int head[N],cnt;inline void add(register int u,register int v){ e[++cnt]=(node){v,head[u]}; head[u]=cnt;}int n,a[N],dfn[N],tim=0,tmp[N];priority_queue q[N];ll ans=0;inline void dfs(register int x){ dfn[x]=++tim; for(register int i=head[x];i;i=e[i].next) { int v=e[i].to; if(dfn[v]) continue; dfs(v); if(q[dfn[x]].size()