求助 90pts
查看原帖
求助 90pts
226113
火羽白日生楼主2021/6/9 21:37

rt

已经调了了一个下午 ++ 一个晚上了

救救孩子

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rint register int
#define fill(x,y) memset(x,y,sizeof(x))
#define copy(x,y) memcpy(y,x,sizeof(x))
#define _File

using namespace std;

inline int read(){
	int w=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9'){w=(w<<3)+(w<<1)+(ch^48); ch=getchar();}
	return w*f;
}

const int maxn=2e5+5,inf=0x3f3f3f3f;

int n,m,L,R;
int col[maxn];//边存的是颜色种类,col存的是权值
namespace Graph{
	int head[maxn],id;
	struct e{
		int v,w,next;
	}edge[maxn<<1];
	inline void add(int u,int v,int w){
		edge[++id].v=v;
		edge[id].w=w;
		edge[id].next=head[u];
		head[u]=id;
	}
}using namespace Graph;
namespace SegmentTree{
	int rt1,rt2,tot;//1 not same;2 same
	struct node{
		int lson,rson,maxx;
		#define lson(x) t[x].lson
		#define rson(x) t[x].rson
		#define maxx(x) t[x].maxx
		node(){lson=rson=0; maxx=-inf;}
		inline void init(){lson=rson=0; maxx=-inf;}
	}t[maxn<<5];
	inline void pushup(int p){
		maxx(p)=max(maxx(lson(p)),maxx(rson(p)));
	}
	inline void del(int &p){t[p].init(); p=0;}
	inline void clear(){
		for(int i=1;i<=tot;i++) t[i].init();
		rt1=rt2=tot=0;
	}
	void update(int &p,int l,int r,int pos,int k){
		if(!p) p=++tot,t[p].init();
		if(l==r) return maxx(p)=max(maxx(p),k),void();
		int mid=(l+r)>>1;
		if(pos<=mid) update(lson(p),l,mid,pos,k);
		else update(rson(p),mid+1,r,pos,k);
		pushup(p);
	}
	int query(int p,int l,int r,int tl,int tr){
		if(!p) return -inf;
		if(tl<=l && r<=tr) return maxx(p);
		int mid=(l+r)>>1,res=-inf;
		if(tl<=mid) res=max(res,query(lson(p),l,mid,tl,tr));
		if(tr>mid) res=max(res,query(rson(p),mid+1,r,tl,tr));
		return res;
	}
	int merge(int x,int y,int l,int r){
		if(!x || !y) return x+y;
		if(l==r){
			maxx(x)=max(maxx(x),maxx(y));
			del(y); return x;
		}
		int mid=(l+r)>>1;
		lson(x)=merge(lson(x),lson(y),l,mid);
		rson(x)=merge(rson(x),rson(y),mid+1,r);
		del(y); pushup(x); return x;
	}
}using namespace SegmentTree;
namespace PointDivide{
	int root,S,top,ans=-inf;
	int size[maxn],wt[maxn];
	bool vis[maxn];
	struct node{int val,dep;}stk[maxn];
	void findroot(int u,int fa){
		size[u]=1; wt[u]=0;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].v;
			if(v==fa || vis[v]) continue;
			findroot(v,u);
			size[u]+=size[v];
			wt[u]=max(wt[u],size[v]);
		}
		wt[u]=max(wt[u],S-size[u]);
		if(wt[u]<wt[root]) root=u;
	}
	void dfs(int u,int fa,int val,int dep,int lstcol){
		if(dep>R) return;
		stk[++top]=(node){val,dep};
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].v,w=edge[i].w;
			if(v==fa || vis[v]) continue;
			dfs(v,u,(w==lstcol)?val:val+col[w],dep+1,w);
		}
	}
	void calc(int u){
		SegmentTree::clear();
		int lstcol=0,flag=0;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].v,w=edge[i].w;
			if(vis[v]) continue;
			top=flag=0;
			dfs(v,u,col[w],1,w);
			if(w==lstcol) flag=1;
			else rt1=merge(rt1,rt2,1,n),rt2=0;
			for(int j=1;j<=top;j++){
				if(flag) ans=max(ans,query(rt2,1,n,max(1,L-stk[j].dep),R-stk[j].dep)+stk[j].val-col[lstcol]);
				ans=max(ans,query(rt1,1,n,max(1,L-stk[j].dep),R-stk[j].dep)+stk[j].val);
				if(stk[j].dep>=L && stk[j].dep<=R) ans=max(ans,stk[j].val);
			}
			for(int j=1;j<=top;j++) update(rt2,1,n,stk[j].dep,stk[j].val);
			lstcol=w;
		}
	}
	void solve(int u){
		vis[u]=1; calc(u);
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].v;
			if(vis[v]) continue;
			S=size[v]; wt[root=0]=inf;
			findroot(v,0); solve(root);
		}
	}
}using namespace PointDivide;

int main(){
	#ifdef _File
		freopen("in","r",stdin);
		freopen("out","w",stdout);
	#endif
	n=read(); m=read(); L=read(); R=read();
	for(int i=1;i<=m;i++) col[i]=read();
	for(int i=1;i<n;i++){
		int x=read(),y=read(),z=read();
		add(x,y,z); add(y,x,z);
	}
	S=wt[root=0]=n;
	findroot(1,0); solve(root);
	printf("%d\n",ans);
	return 0;
}
2021/6/9 21:37
加载中...