LGP3642题解
whk 了两天,来口胡一道题放松放松。
设 表示子树中所有叶子都距离自己的父亲节点长度为 的最小代价。(定义 号节点的父亲节点为 ,距离为 )
不难发现有 。其中 表示父亲到自己的边权。
我们可以证明,若 ,那么 是一个分段一次函数,并且是一个单谷函数。
对于后面的 可以看做是将若干分段函数加起来。将分段函数求导后会单调不增,加起来后一定仍然单调不增。
对于前面的加绝对值,可以把将边权变长和将边权变短分开讨论。
将边权变短类似于 。
将边权变长类似于 。
显然可以先变长再变短,这样是无所谓的。
可以发现边权变短相当于是在谷点的前面加了一段斜率为 长度为 的一次函数,变长相当于是把斜率对 取 。
使用平衡树维护分段函数,只维护分段函数的斜率以及其在 处的值(其实就是边权之和),复杂度 。不知道 16 年的机子能不能跑。
但是当分段函数特殊时是可以使用堆维护分段点的,表示每经过一个分段点斜率就减小 。
很显然一次操作结束后的分段函数最右边那个分段点代表的是右边斜率为 。
于是可以使用可并堆维护分段点的最大值,每次弹出最大的两个然后将弹出值加上 后再插回去即是将边权变短的操作。
然后再 pop 儿子数量-1 个分割点即可使最右侧的斜率为 。
只需要写左偏树,且复杂度为 。
#include<cstdio>
#include<cctype>
namespace SOLVE{
inline int read(){
int n(0);char s;while(!isdigit(s=getchar()));while(n=n*10+(s&15),isdigit(s=getchar()));return n;
}
typedef long long ll;
const int M=3e5+5;
int n,ege,h[M];int tot,d[M<<1],ls[M<<1],rs[M<<1];ll w[M<<1];
struct Edge{
int v,nx;ll w;
}e[M];
inline void swap(int&a,int&b){
int c=a;a=b;b=c;
}
inline void Add(const int&u,const int&v,const ll&w){
e[++ege]=(Edge){v,h[u],w};h[u]=ege;
}
inline int merge(const int&q,const int&p){
if(!q||!p)return q|p;if(w[q]<w[p])return merge(p,q);
rs[q]=merge(rs[q],p);if(d[rs[q]]>d[ls[q]])swap(ls[q],rs[q]);d[q]=d[rs[q]]+1;return q;
}
inline int DFS(const int&u,const int&V){
int rt(0),cnt(-1);for(int E=h[u];E;E=e[E].nx)rt=merge(rt,DFS(e[E].v,e[E].w)),++cnt;
if(~cnt)while(cnt--)rt=merge(ls[rt],rs[rt]);if(u==1)return rt;
const ll&X=w[rt]+V;rt=merge(ls[rt],rs[rt]);const ll&Y=w[rt]+V;rt=merge(ls[rt],rs[rt]);
w[++tot]=X;d[tot]=1;rt=merge(rt,tot);w[++tot]=Y;d[tot]=1;rt=merge(rt,tot);return rt;
}
inline void main(){
ll sum(0);n=read()+read();for(int f,w,i=2;i<=n;++i)f=read(),w=read(),Add(f,i,w),sum+=w;
int rt=DFS(1,0);while(rt=merge(ls[rt],rs[rt]))sum-=w[rt];printf("%lld",sum);
}
}
signed main(){
SOLVE::main();
}
本文作者:Prean
本文链接:https://www.cnblogs.com/lmpp/p/16722695.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端