P3780 90分求调
  • 板块灌水区
  • 楼主xyz123
  • 当前回复0
  • 已保存回复0
  • 发布时间2025/2/7 23:00
  • 上次更新2025/2/8 08:55:19
查看原帖
P3780 90分求调
379926
xyz123楼主2025/2/7 23:00

第二个点错了

#include<bits/stdc++.h>
using namespace std;
const int N=20010,M=500010;
int h1[N],e1[N],ne1[N],idx1;
void add1(int a,int b){e1[++idx1]=b;ne1[idx1]=h1[a];h1[a]=idx1;}
int h2[N],e2[N],ne2[N],idx2;
void add2(int a,int b){e2[++idx2]=b;ne2[idx2]=h2[a];h2[a]=idx2;}
int f[N],c[N],v[N];
long long dep[N];
inline int read(){
	char ch=getchar();int x=0;
	while(!isdigit(ch))	ch=getchar();
	while(isdigit(ch)){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x;
}
int que[M],fr,tl,n,k;
const int V=26000000;
long long f1[V],f2[V];
inline int getv(int i,int j){return i*(k+1)+j;}
void dfs1(int u){
	fr=0,tl=1;que[1]=0;
	for(int i=1;i<=k;i++){
		while(fr<tl&&que[fr+1]+(c[u]-1)<i)	fr++;
		f1[getv(u,i)]=max(f1[getv(f[u],i)],f1[getv(f[u],que[fr+1])]+(i-que[fr+1])*1ll*v[u]);
		while(fr<tl&&f1[getv(f[u],que[tl])]-que[tl]*1ll*v[u]<=f1[getv(f[u],i)]-i*1ll*v[u])	tl--;
		que[++tl]=i;
	}
	for(int i=h1[u];i;i=ne1[i]){
		int j=e1[i];dfs1(j);
	}
	for(int i=1;i<=k;i++)	f1[getv(f[u],i)]=max(f1[getv(f[u],i)],f1[getv(u,i-1)]+v[u]);
}
void dfs2(int u){
	for(int i=0;i<=k;i++)	f2[getv(u,i)]=f2[getv(f[u],i)];
	for(int i=h2[u];i;i=ne2[i]){
		int j=e2[i];dfs2(j);
	}
	fr=0,tl=1;que[1]=0;
	for(int i=0;i<=k;i++){
		while(fr<tl&&que[fr+1]+c[u]<i)	fr++;
		f2[getv(f[u],i)]=max(f2[getv(f[u],i)],f2[getv(u,que[fr+1])]+(i-que[fr+1])*1ll*v[u]);
		while(fr<tl&&f2[getv(u,que[tl])]-que[tl]*1ll*v[u]<=f2[getv(u,i)]-i*1ll*v[u])	tl--;
		que[++tl]=i;
	}
}
long long ans;
void dfs3(int u){
	int cnt=0;
	for(int i=h1[u];i;i=ne1[i]){
		int j=e1[i];cnt++;
		dfs3(j);
	}
	if(!cnt){
		for(int i=0;i<=k;i++)	ans=max(ans,f1[getv(u,i)]+f2[getv(u,k-i)]+dep[u]);
	}
}
void work(){
	memset(f1,0,sizeof f1);memset(f2,0,sizeof f2);
	memset(h1,0,sizeof h1);memset(h2,0,sizeof h2);idx1=idx2=0;
	n=read(),k=read();
	for(int i=1;i<=n;i++){f[i]=read();c[i]=read();v[i]=read();add1(f[i],i);}
	for(int i=1;i<=n;i++)	dep[i]=dep[f[i]]+v[i];
	for(int i=n;i>=1;i--)	add2(f[i],i);
	dfs1(1);dfs2(1);
	ans=0;dfs3(1);
	printf("%lld\n",ans);
	return;
}
int main(){
	int q=read();
	while(q--)	work();
	return 0;
}
2025/2/7 23:00
加载中...