社区讨论

为什么会CE

P6326Shopping参与者 3已保存回复 6

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
6 条
当前快照
1 份
快照标识符
@mhj3s4zc
此快照首次捕获于
2025/11/03 20:15
4 个月前
此快照最后确认于
2025/11/03 20:15
4 个月前
查看原帖
rt, DSU on tree, Hydro上过了, Luogu CE
本地无编译错误
CPP
// Problem: P6326 Shopping
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P6326
// Memory Limit: 125 MB
// Time Limit: 1500 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
const int N=505,M=4005,Len=1e6+10;
#define pii pair<int,int>
#define fi first
#define se second
struct deQue{
	pii index[Len];
	int st=1,ed=0;
	int sz(){return ed-st+1;}
	void cls(){
		st=1;ed=0;
	}
	void empl(pii a){
		index[++ed]=a;
	}
	void popb(){
		--ed;
	}
	void popf(){
		++st;
	}
	pii& front(){
		return index[st];
	}
	pii& back(){
		return index[ed];
	}
};
deQue Que;
int n,m,w[N],v[N],a[N],dfn[N],rdfn[N],dson[N],tot;
int dp[N][M],tmp[M];
vector<int> g[N];
int sz[N];
void dfs1(int u,int fa){
	sz[u]=1;
	for(auto v:g[u]){
		if(v!=fa){
			dfs1(v,u);
			sz[u]+=sz[v];
			if(sz[v]>sz[dson[u]]){
				dson[u]=v;
			}
		}
	}
}
void dfs2(int u,int fa){
	dfn[u]=++tot;rdfn[dfn[u]]=u;
	if(dson[u]){dfs2(dson[u],u);}
	for(auto v:g[u]){
		if(v!=dson[u]&&v!=fa)dfs2(v,u);
	}
}

void calthis(int u){
	rep(i,dfn[u]+1,dfn[u]+sz[u])rep(j,0,m)dp[i][j]=-1e16;
	rep(i,dfn[u],dfn[u]+sz[u]-1){
		int nd=rdfn[i];
		//int bas=min(m,v[nd]-1);
		int bas=min(m,v[nd]-1);
		//pack
		rep(b,0,bas){
			Que.cls();
			for(int j=0;b+j*v[nd]<=m;j++){
				while(Que.sz()&&Que.front().fi<j-a[nd])Que.popf();
				if(Que.sz())dp[i+1][b+j*v[nd]]=max(dp[i+1][b+j*v[nd]],Que.front().se+j*w[nd]);
				while(Que.sz()&&Que.back().se<=dp[i][b+j*v[nd]]-j*w[nd]){
					Que.popb();
				}Que.empl({j,dp[i][b+j*v[nd]]-j*w[nd]});
			}
		}
		//npack
		rep(j,0,m)dp[i+sz[rdfn[i]]][j]=max(dp[i+sz[rdfn[i]]][j],dp[i][j]);
	}
}
int Ans=-1e16;
void dsu(int u,int fa){
	for(auto v:g[u]){
		if(v!=dson[u]&&v!=fa)dsu(v,u);
	}
	if(dson[u]){
		dsu(dson[u],u);
		int v=dson[u];
		rep(j,0,m+1)tmp[j]=-1e16;
		
		int tar=dfn[v]+sz[v];
		
		
		//not choose v is ok 
		dp[tar][0]=max(dp[tar][0],0ll);
		
		int nd=u;
		//int bas=min(m,v[nd]-1);
		int bas=min(m,::v[nd]-1);
		//but you has to choose u
		rep(b,0,bas){
			Que.cls();
			for(int j=0;b+j*::v[nd]<=m;j++){
				while(Que.sz()&&Que.front().fi<j-a[nd])Que.popf();
				if(Que.sz())tmp[b+j*::v[nd]]=max(tmp[b+j*::v[nd]],Que.front().se+j*w[nd]);
				while(Que.sz()&&Que.back().se<=dp[tar][b+j*::v[nd]]-j*w[nd]){
					Que.popb();
				}Que.empl({j,dp[tar][b+j*::v[nd]]-j*w[nd]});
			}
		}
		rep(j,0,m+1)dp[tar][j]=tmp[j];
		for(auto v:g[u]){
			if(v!=dson[u]&&v!=fa)calthis(v);
		}
	}else{ //u leaf but must be chosen
		rep(j,0,m+1)dp[dfn[u]+sz[u]][j]=-1e16;
		rep(j,1,m)if(j%v[u]==0&&(j/v[u])<=a[u])dp[dfn[u]+sz[u]][j]=(j/v[u])*w[u];
	}
	rep(j,0,m)Ans=max(Ans,dp[dfn[u]+sz[u]][j]);
}
void sol(){
	cin>>n>>m;Ans=-1e16;
	rep(i,1,n)cin>>w[i];
	rep(i,1,n)cin>>v[i];
	rep(i,1,n)cin>>a[i];
	rep(i,0,n+1)dson[i]=0;
	rep(i,0,n+1)g[i].clear();
	rep(i,1,n-1){
		int u,v;cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	tot=0;
	dfs1(1,0);dfs2(1,0);
	rep(i,0,n+1)rep(j,0,m+1)dp[i][j]=-1e16;
	dsu(1,0);
	cout<<Ans<<endl;
}
signed main(){
	int t;cin>>t;
	while(t--)sol();
}

回复

6 条回复,欢迎继续交流。

正在加载回复...