求助,样例过不去
查看原帖
求助,样例过不去
252549
Iwara楼主2024/4/13 09:58

RT

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=1e5+5;
ll n,l,r,x,y,z,L=1e15,R=-1e15,mid;
struct edge{
	ll u,v,w,nxt;
}e[MAXN<<1],tmp[MAXN<<1];
ll head[MAXN],edge_num;
void add_edge(ll From,ll To,ll Len){
	edge_num++;
	e[edge_num].u=From;
	e[edge_num].v=To;
	e[edge_num].w=Len;
	e[edge_num].nxt=head[From]; 
	head[From]=edge_num;
	return;
}
struct sgm_t{
	ll data[MAXN<<2];
	void clear(){
		for(int i=1;i<=(n<<2);i++)data[i]=-1e15;
		return;
	}
	void push_up(ll id){
		data[id]=max(data[id<<1],data[id<<1|1]);
		return;
	}
	void update(ll id,ll L,ll R,ll pos,ll delta){
		if(L>R||pos<L||pos>R)return;
		if(L==R){
			data[id]=max(data[id],delta);
			return;
		} 
		ll mid=(L+R)>>1;
		if(pos<=mid)update(id<<1,L,mid,pos,delta);
		else update(id<<1|1,mid+1,R,pos,delta);
		push_up(id);
		return;
	}
	ll query(ll id,ll L,ll R,ll QL,ll QR){
		if(L>R||QR<L||R<QL)return 0;
		if(QL<=L&&R<=QR)return data[id];
		ll mid=(L+R)>>1;
		return max(query(id<<1,L,mid,QL,QR),query(id<<1|1,mid+1,R,QL,QR));
	}
}S;
ll sz[MAXN],max_sz[MAXN],sum,dis[MAXN],rt,res;
bool vis[MAXN];
void calc_sz(ll now,ll father){
	sz[now]=1;
	max_sz[now]=0;
	for(int i=head[now];i;i=e[i].nxt){
		if(vis[e[i].v]||e[i].v==father)continue;
		calc_sz(e[i].v,now);
		max_sz[now]=max(max_sz[now],sz[e[i].v]);
		sz[now]+=sz[e[i].v];
	}
	max_sz[now]=max(max_sz[now],sum-sz[now]);
	if(max_sz[now]<max_sz[rt]||!rt)rt=now;
	return;
}
ll reg[MAXN];
void calc_dis(ll now,ll father,ll deep){
	if(deep>r)return;
	reg[deep]=max(reg[deep],dis[now]);
	for(int i=head[now];i;i=e[i].nxt){
		if(vis[e[i].v]||e[i].v==father)continue;
		dis[e[i].v]=dis[now]+e[i].w;
		calc_dis(e[i].v,now,deep+1);
	}
	return;
}
void solve(ll now,ll father){
	if(res)return;
	vis[now]=1;
	S.clear();
	for(int i=head[now];i;i=e[i].nxt){
		if(vis[e[i].v]||e[i].v==father)continue;
		dis[e[i].v]=e[i].w;
		for(int j=1;j<=r;j++)reg[j]=-1e15;
		calc_dis(e[i].v,now,1);
		for(int j=0;j<=r;j++)if(reg[j]+S.query(1,1,n,l-j,r-j)>0){
			res=1;
			break;
		}
		for(int j=1;j<=r;j++)S.update(1,1,n,j,reg[j]);
	}
	for(int i=head[i];i;i=e[i].nxt){
		if(vis[e[i].v]||e[i].v==father)continue;
		sum=sz[e[i].v];
		rt=0;
		calc_sz(e[i].v,now);
		calc_sz(rt,-1);
		solve(rt,now);
	}
	return;
}
bool check(ll num){
	for(int i=1;i<=edge_num;i++)tmp[i]=e[i],tmp[i].w=tmp[i].w>=num?1:-1;
	for(int i=1;i<=edge_num;i++)swap(e[i],tmp[i]);
	for(int i=1;i<=n;i++)vis[i]=0,sz[i]=0,max_sz[i]=0;
	rt=0;
	calc_sz(1,-1);
	calc_sz(rt,-1);
	res=0;
	solve(rt,-1);
	for(int i=1;i<=edge_num;i++)swap(e[i],tmp[i]);
//	cout<<"?\n";
	return res;
}
void print_ans(ll now,ll father,ll deep){
	if(l<=deep&&deep<=r&&dis[now]>0){
		cout<<rt<<" "<<now;
		exit(0);
	}
	for(int i=head[now];i;i=e[i].nxt){
		if(e[i].v==father)continue;
		dis[e[i].v]=dis[now]+e[i].w;
		print_ans(e[i].v,now,deep+1);
	} 
	return;
}
int main(){
	cin>>n>>l>>r;
	for(int i=1;i<n;i++){
		cin>>x>>y>>z;
		L=min(L,z);
		R=max(R,z); 
		add_edge(x,y,z);
		add_edge(y,x,z);
	}
	while(L<=R){
		mid=(L+R)>>1;
		if(check(mid))R=mid-1;
		else L=mid+1;
	}
//	cout<<L<<endl;
	for(int i=1;i<=edge_num;i++)tmp[i]=e[i],tmp[i].w=tmp[i].w>=L?1:-1;
	for(int i=1;i<=edge_num;i++)swap(e[i],tmp[i]);
	for(int i=1;i<=n;i++)dis[i]=0;
	for(int i=1;i<=n;i++){
		rt=i;
		dis[i]=0;
		print_ans(rt,-1,0);
	}
	return 0;
}

请忽略我超级劣质的写法/ll

感觉没问题啊/ll

2024/4/13 09:58
加载中...