MnZn刚学OI1ms玄关求调
查看原帖
MnZn刚学OI1ms玄关求调
754310
Pepsee楼主2024/5/6 21:20

rt,Wa on #2 #8,用平衡树维护的dep和col的最大值,求hack或者找错,qwq

#include <bits/stdc++.h>
using namespace std;
namespace IO{
	char buff[1<<21],*p1=buff,*p2=buff;
	char getch(){return p1==p2&&(p2=((p1=buff)+fread(buff,1,1<<21,stdin)),p1==p2)?EOF:*p1++;}
	template<typename T>
	void read(T &x) {char ch=getch();int fl=1;x=0;while(ch>'9'||ch<'0'){if(ch=='-')fl=-1;ch=getch();}while(ch<='9'&&ch>='0') {x=x*10+ch-48;ch=getch();}x*=fl;}
	template<typename T,typename ...Args>
	void read(T &x,Args& ...args){read(x);read(args...);}
	char obuf[1<<21],*p3=obuf;
	void putch(char ch){if(p3-obuf<(1<<21))*p3++=ch;else fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=ch;}
	char ch[100]; template<typename T>
	void write(T x){if(!x)return putch('0');if(x<0)putch('-'),x*=-1;int top=0;while(x)ch[++top]=x%10+48,x/=10;while(top)putch(ch[top]),top--;}
	template<typename T,typename ...Args>
	void write(T x,Args ...args){write(x);write(args...);}
	void flush(){fwrite(obuf,p3-obuf,1,stdout);}
}
using namespace IO;

int n,m,l,r,ans = -2e9;
int c[200005];
int siz[200005],son[200005],Size;
int rt,vis[200005];
int sum[200005],dis[200005];
int head[200005],tot;
struct s1mple{int d,s;} val[200005];
struct node{int nex,to,c;} edge[200005<<1];
inline void add(int x,int y,int c){edge[++tot].nex = head[x]; edge[tot].to = y; edge[tot].c = c; head[x] = tot;}
namespace elia//fhq压行了 
{
	int cnt,root,a,b,c,x,y,z;
	struct fhq{int ls,rs,Dis,Col; int rnd,val,mx;} tr[20000005];
	inline int New(int v,int Dis,int Col){++cnt; tr[cnt].val = tr[cnt].mx = v; tr[cnt].Col = Col; tr[cnt].Dis = Dis; tr[cnt].rnd = rand(); tr[cnt].ls = tr[cnt].rs = 0; return cnt;}
	void update(int rt)
	{
		if (rt) tr[rt].mx = tr[rt].val;
		if (tr[rt].ls) tr[rt].mx = max(tr[rt].mx,tr[tr[rt].ls].mx);
		if (tr[rt].rs) tr[rt].mx = max(tr[rt].mx,tr[tr[rt].rs].mx);
	}
	void c_split(int rt,int val,int &x,int &y)//按颜色分裂 
	{
		if (!rt){x = y = 0; return ;}
		if (tr[rt].Col <= val){x = rt; c_split(tr[x].rs,val,tr[x].rs,y);}
		else{y = rt; c_split(tr[y].ls,val,x,tr[y].ls);}
		update(rt);
	}
	void d_split(int rt,int val,int &x,int &y)//按深度分裂
	{
		if (!rt){x = y = 0;return ;}
		if (tr[rt].Dis <= val){x = rt; d_split(tr[x].rs,val,tr[x].rs,y);}
		else{y = rt; d_split(tr[y].ls,val,x,tr[y].ls);}
		update(rt);
	}
	int merge(int x,int y)
	{
		if (!x || !y) return x|y;
		if (tr[x].rnd < tr[y].rnd){tr[x].rs = merge(tr[x].rs,y); update(x); return x;}
		else{tr[y].ls = merge(x,tr[y].ls); update(y); return y;}
	}
	inline void insert(int v,int Dis,int Col)
	{
		c_split(root,Col,b,c); c_split(b,Col-1,a,b);
		d_split(b,Dis,y,z); d_split(y,Dis-1,x,y);
		if (!y) y = New(v,Dis,Col);
		else tr[y].val = max(tr[y].val,v),tr[y].mx = tr[y].val;
		b = merge(merge(x,y),z); root = merge(merge(a,b),c);
	}
	inline int same(int l,int r,int Col)//同色贡献 
	{
		int res = -2e9;
		c_split(root,Col,b,c); c_split(b,Col-1,a,b);
		d_split(b,r,y,z); d_split(y,l-1,x,y);
		if (y) res = tr[y].mx;
		b = merge(merge(x,y),z); root = merge(merge(a,b),c);
		return res;
	}
	inline int diff(int l,int r,int Col)//异色贡献 
	{
		int res = -2e9;
		c_split(root,Col-1,a,b); d_split(a,r,y,z); d_split(y,l-1,x,y);
		if (y) res = tr[y].mx;
		a = merge(merge(x,y),z); root = merge(a,b);
		c_split(root,Col,a,b); d_split(b,r,y,z); d_split(y,l-1,x,y);
		if (y) res = max(res,tr[y].mx);
		b = merge(merge(x,y),z); root = merge(a,b);
		return res;
	}
	inline pair<int,int> query(int l,int r,int Col){if(l>r)return make_pair(-2e9,-2e9); return make_pair(same(l,r,Col),diff(l,r,Col));}
}
void get_root(int x,int fa)
{
	son[x] = 0; siz[x] = 1;
	for (int i = head[x]; i; i = edge[i].nex)
	{
		int v = edge[i].to;
		if (v == fa || vis[v]) continue;
		get_root(v,x);
		siz[x] += siz[v];
		son[x] = max(son[x],siz[v]);
	}
	son[x] = max(son[x],Size-siz[x]);
	if (son[x] < son[rt]) rt = x;
}
void get_dis(int x,int fa,int col)
{
	++tot;
	val[tot] = (s1mple){dis[x],sum[x]};
	for (int i = head[x]; i; i = edge[i].nex)
	{
		int v = edge[i].to,cl = edge[i].c;
		if (v == fa || vis[v]) continue;
		dis[v] = dis[x]+1;
		sum[v] = sum[x]+(col!=cl)*c[cl];
		get_dis(v,x,cl);
	}
}
void clac(int x)
{
	elia::root = 0;
	while (elia::cnt) elia::tr[elia::cnt--] = (elia::fhq){0,0,0,0,0,0,0};//清空 
	elia::tr[elia::cnt] = (elia::fhq){0,0,0,0,0,0,0};
	for (int i = head[x]; i; i = edge[i].nex)
	{
		int v = edge[i].to,cl = edge[i].c;
		if (vis[v]) continue;
		dis[v] = 1; sum[v] = c[cl];
		tot = 0;
		get_dis(v,x,cl);
		for (int i = 1; i <= tot; i++)
		{
			if (val[i].d > r) continue;
			if (val[i].d >= l) ans = max(val[i].s,ans);
			pair<int,int> res = elia::query(max(1,l-val[i].d),r-val[i].d,cl);
			ans = max(ans,res.first+val[i].s-c[cl]);//同色 
			ans = max(ans,res.second+val[i].s);//异色 
		}
		for (int i = 1; i <= tot; i++)
			if (val[i].d < r) elia::insert(val[i].s,val[i].d,cl);
	}
}
void solve(int x)
{
	vis[x] = 1;	
	clac(x);
	for (int i = head[x]; i; i = edge[i].nex)
	{
		int v = edge[i].to;
		if (vis[v]) continue;
		Size = siz[v]; rt = 0;
		get_root(v,x);
		solve(rt);
	}
}
signed main()
{
	read(n,m,l,r);
	for (int i = 1; i <= m; i++)
		read(c[i]);
	for (int i = 1,u,v,c; i < n; i++)
		read(u,v,c),add(u,v,c),add(v,u,c);
	son[0] = Size = n;
	get_root(1,0);
	solve(rt);
	write(ans);
	flush();
	return 0;
}
2024/5/6 21:20
加载中...