40pts全T求调
查看原帖
40pts全T求调
300370
flyfreemrn楼主2025/1/3 18:55

淀粉汁+线段树做法

using namespace std;
#define ll long long
#define inf 1e18
#define MAXN 1000010
#define pir pair<ll,ll>
#define mp make_pair
#define debug cout<<"flyfree\n";
// By flyfreemrn
inline ll read(){
	ll x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-')f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}
inline void write(ll x){
	if(x>9)write(x/10);
	putchar(x%10+'0');
}
struct node_sgt{
	ll l[MAXN*4],r[MAXN*4],maxz[MAXN*4];
	void build(ll lz,ll rz,ll now){
		l[now]=lz,r[now]=rz,maxz[now]=-inf;
		if(lz==rz)return;
		ll mid=(lz+rz)/2;
		build(lz,mid,now*2);
		build(mid+1,rz,now*2+1);
	}
	ll _find(ll lz,ll rz,ll now){
		if(l[now]>=lz&&r[now]<=rz)return maxz[now];
		ll mid=(l[now]+r[now])/2,ans=-inf;
		if(lz<=mid)ans=max(ans,_find(lz,rz,now*2));
		if(rz>mid)ans=max(ans,_find(lz,rz,now*2+1));
		return ans;
	}
	void insert(ll pos,ll val,ll now){
		maxz[now]=max(maxz[now],val);
		if(l[now]==r[now])return;
		ll mid=(l[now]+r[now])/2;
		if(pos<=mid)insert(pos,val,now*2);
		else insert(pos,val,now*2+1);
	}
	void clear(ll pos,ll now){
		maxz[now]=-inf;
		if(l[now]==r[now])return;
		ll mid=(l[now]+r[now])/2;
		if(pos<=mid)clear(pos,now*2);
		else clear(pos,now*2+1);
	}
}sgt1,sgt2;
bool used[MAXN];
vector<pir> vec[MAXN];
ll n,m,l,r,min_siz,id,ans=-inf;
ll siz[MAXN],maxu[MAXN],val[MAXN],dep[MAXN],len[MAXN];
vector<ll> q,sam;
void mk_siz(ll now,ll fa){
	siz[now]=1;
	for(int i=0;i<vec[now].size();i++){
		ll y=vec[now][i].second;
		if(used[y]||y==fa)continue;
		mk_siz(y,now);
		siz[now]+=siz[y];
	}
}
void _find(ll now,ll fa,ll tot){//当前节点,父节点,总点数 
	maxu[now]=tot-siz[now];
	for(int i=0;i<vec[now].size();i++){
		ll y=vec[now][i].second;
		if(y==fa||used[y])continue;
		_find(y,now,tot);
		maxu[now]=max(maxu[now],siz[y]);
	}
	if(maxu[now]<min_siz)min_siz=maxu[now],id=now;
}
void dfs(ll now,ll fa,ll _dep,ll _len,ll _col){//当前点,父节点,深度,长度,颜色 
	dep[now]=_dep,len[now]=_len;
	q.push_back(now);
	for(int i=0;i<vec[now].size();i++){
		ll y=vec[now][i].second,col=vec[now][i].first;
		if(used[y]||y==fa)continue;
		dfs(y,now,_dep+1,(_col==col)?_len:_len+val[col],col);
	}
}
void clear(ll now,ll fa){
	if(dep[now]<=r)sgt1.clear(dep[now],1);
	dep[now]=len[now]=0;
	for(int i=0;i<vec[now].size();i++){
		ll y=vec[now][i].second;
		if(used[y]||y==fa)continue;
		clear(y,now);
	}
}
void solve(ll now){
	cout<<"now:"<<now<<endl;
//	debug;
	ll it=0;
	for(int i=1;i<=m;i++){
//		cout<<i<<endl;
		while(it<vec[now].size()){
			if(vec[now][it].first<=i){
//				cout<<it<<" "<<vec[now].size()<<" "<<vec[now][it].second<<endl;
				ll s=vec[now][it].second;
				it++;
				if(used[s])continue;
//				debug;
//				cout<<it<<endl;
				dfs(s,now,1,0,i);
//				debug;
				for(int j=0;j<q.size();j++){//查找答案 
					ll y=q[j];
					sam.push_back(y);
					if(used[y]||dep[y]>r)continue;
					ll ans1=sgt1._find(max(0ll,l-dep[y]),r-dep[y],1),ans2=sgt2._find(max(0ll,l-dep[y]),r-dep[y],1);
					//ans1不同颜色答案,ans2同颜色答案 
					ans=max(ans,max(ans1,ans2)+len[y]+val[i]);
				}
//				debug;
				for(int j=0;j<q.size();j++){
					ll y=q[j];
					if(used[y]||dep[y]>r)continue;
					sgt2.insert(dep[y],len[y],1);
					//修改 
				}
				q.clear();
//				it++;
			}else break;
		}
//		debug;
		for(int j=0;j<sam.size();j++){
			ll y=sam[j];
			if(used[y]||dep[y]>r)continue;
			sgt1.insert(dep[y],len[y]+val[i],1);//线段树1修改 
			sgt2.clear(dep[y],1);//线段树2清空 
		}
		sgt2.insert(0,0,1);
//		cout<<i<<endl;
		sam.clear();
	}
	for(int i=0;i<vec[now].size();i++){//线段树1清空 
		ll y=vec[now][i].second;
		if(used[y])continue;
		clear(y,now);
	} 
	sgt1.insert(0,0,1);
//	debug;
	used[now]=true;
	for(int i=0;i<vec[now].size();i++){
		ll y=vec[now][i].second;
		if(used[y])continue;
		mk_siz(y,now);
		min_siz=inf,id=0;
		_find(y,now,siz[y]);
		solve(id);
	}
}
int main(){
	n=read(),m=read(),l=read(),r=read();
	sgt1.build(0,n,1),sgt2.build(0,n,1);
	sgt1.insert(0,0,1),sgt2.insert(0,0,1);
	for(int i=1;i<=m;i++)val[i]=read();
	for(int i=1;i<n;i++){
		ll x=read(),y=read(),z=read();
		vec[x].push_back(mp(z,y));
		vec[y].push_back(mp(z,x));
	}
	for(int i=1;i<=n;i++)sort(vec[i].begin(),vec[i].end());
	mk_siz(1,1);
	min_siz=inf,id=0;
	_find(1,1,siz[1]);
	solve(id);
	cout<<ans;
	return 0;
}```
2025/1/3 18:55
加载中...