一、题目描述:
给你一个
对于每一个点
那么点
数据范围:
二、解题思路:
思路很明显,直接从儿子向父亲合并信息即可。
然后不停的
用的是左偏树,时间复杂度
三、完整代码:
1 #include<iostream> 2 #define N 100010 3 #define d(p) t[p].d 4 #define ls(p) t[p].ls 5 #define rs(p) t[p].rs 6 #define val(p) t[p].val 7 using namespace std; 8 int n,m,fa; 9 long long ans,sum[N]; 10 int a[N],rt[N],size[N]; 11 struct EDGE{ 12 int v,nxt; 13 }edge[N]; 14 int head[N],cnt; 15 void add(int u,int v) 16 { 17 edge[++cnt].v=v; 18 edge[cnt].nxt=head[u]; 19 head[u]=cnt; 20 } 21 struct Node{ 22 int d,ls,rs,val; 23 }t[N]; 24 int merge(int p,int q) 25 { 26 if(!p||!q) return p|q; 27 if(val(p)<val(q)) swap(p,q); 28 rs(p)=merge(rs(p),q); 29 if(d(ls(p))<d(rs(p))) swap(ls(p),rs(p)); 30 d(p)=d(rs(p))+1; return p; 31 } 32 int pop(int u) 33 { 34 size[u]--;sum[u]-=val(rt[u]); 35 return merge(ls(rt[u]),rs(rt[u])); 36 } 37 void dfs(int u) 38 { 39 for(int i=head[u];i!=-1;i=edge[i].nxt) 40 { 41 int to=edge[i].v;dfs(to); 42 rt[u]=merge(rt[u],rt[to]); 43 sum[u]+=sum[to],size[u]+=size[to]; 44 while(sum[u]>m) rt[u]=pop(u); 45 } 46 while(sum[u]>m) rt[u]=pop(u); 47 ans=max(ans,1ll*size[u]*a[u]); 48 } 49 int main() 50 { 51 ios::sync_with_stdio(false); 52 cin.tie(0);cout.tie(0); 53 cin>>n>>m;t[0].d=-1; 54 for(int i=1;i<=n;i++) 55 head[i]=-1; 56 for(int i=1;i<=n;i++) 57 { 58 cin>>fa>>val(i)>>a[i];rt[i]=i; 59 add(fa,i),sum[i]=val(i),size[i]=1; 60 } 61 dfs(1);cout<<ans<<'\n'; 62 return 0; 63 }
四、写题心得:
算是左偏树模板,没什么思维难度,收获经验如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】