斜堆,样例通过,0分求助
查看原帖
斜堆,样例通过,0分求助
989792
lrx___楼主2025/1/18 13:45
#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define debug(...)
#endif
using namespace std;
using namespace chrono;
typedef long long i64;

constexpr int N(1e5+5);
int n,m,root,rt[N],sz[N],fa[N],cost[N],lead[N];
i64 ans,sum[N];
struct node{
	int ch[2];
}t[N];

#define ls(u) t[u].ch[0]
#define rs(u) t[u].ch[1]
#define sum(u) t[u].sum
#define dir(u) rs(fa(u))==u
int merge(int u,int v){
	if(!u||!v){
		return u|v;
	}
	if(cost[u]<cost[v]){
		swap(u,v);
	}
	rs(u)=merge(rs(u),v);
	swap(ls(u),rs(u));
	return u;
}
void erase(int& r){
	int new_sz{sz[r]-1};
	i64 new_sum{sum[r]-cost[r]};
	r=merge(ls(r),rs(r));
	sum[r]=new_sum;
	sz[r]=new_sz;
}
namespace tree{
	int h[N],p;
	struct edge{
		int p,v;
	}e[N];
	void add_dir_edge(int u,int v){
		e[++p].p=h[u];
		e[p].p=v;
		h[u]=p;
	}
	void dfs(int u){
		int i,v,new_root;
		sz[rt[u]]=1;
		sum[rt[u]]=cost[u];
		for(i=h[u];i;i=e[i].p){
			v=e[i].v;
			dfs(v);
			new_root=merge(rt[u],rt[v]);
			sum[new_root]=sum[rt[u]]+sum[rt[v]];
			sz[new_root]=sz[rt[u]]+sz[rt[v]];
			rt[u]=new_root;
			while(sum[rt[u]]>m){
				erase(rt[u]);
			}
		}
		ans=max(ans,sz[rt[u]]*(i64)(lead[u]));
	}
}
int main() {
	int i;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;++i){
		scanf("%d%d%d",fa+i,cost+i,lead+i);
		if(!fa[i]){
			root=i;
		}else{
			tree::add_dir_edge(fa[i],i);
		}
	}
	tree::dfs(root);
	printf("%lld\n",ans);
	return 0;
}
2025/1/18 13:45
加载中...