#13TLE 95pts求助
查看原帖
#13TLE 95pts求助
1217201
liyunhe楼主2025/1/24 13:10
#include<bits/stdc++.h>
#define db 0
using namespace std;
const int MAXM=3e8+5;
const int MAXN=3e5+5;
const int MAXP=20;
int n,m;
struct node{int v,t;};
vector<node>eg[MAXN];
int deep[MAXN],s[MAXN];
int a[MAXN*2],cnt;
int st[MAXN*2][MAXP];
struct line{
	int u,v;
	int lca,t;
}lines[MAXN];
void DFS(int x,int fa){
	a[++cnt]=x;
	s[x]=cnt;
	for(auto to:eg[x]){
		if(to.v==fa)continue;
		deep[to.v]=deep[x]+to.t;
		DFS(to.v,x);
		a[++cnt]=x;
	}
}
int min_deep(int x,int y){
	return deep[x]<deep[y]?x:y;
}
void buildST(){
	for(int i=1;i<=cnt;i++)st[i][0]=a[i];
	for(int j=1;(1<<j)<=cnt;j++){
		for(int i=1;i+(1<<j)-1<=cnt;i++){
			st[i][j]=min_deep(st[i][j-1],st[i+(1<<(j-1))][j-1]);
		} 
	}
}
int LCA(int a,int b){
	int l=s[a],r=s[b];
	if(l>r)swap(l,r);
	int k=(int)(log(r-l+1)/log(2));
	return min_deep(st[l][k],st[r-(1<<k)+1][k]);
}
int acc[MAXN],dif[MAXN],q[MAXN],maxdel,overcot;
void check_dfs(int x,int fa){
	acc[x]+=dif[x];
	for(auto to:eg[x]){
		if(to.v==fa)continue;
		check_dfs(to.v,x);
		acc[x]+=acc[to.v];
		if(acc[to.v]==overcot){
			maxdel=max(maxdel,to.t);
		}
	}
}
bool check(int k){
	memset(acc,0,sizeof(acc));
	memset(dif,0,sizeof(dif));
	memset(q,0,sizeof(q));
	maxdel=0;
	overcot=0;
	int st=0,ed=0;
	for(int i=1;i<=m;i++){
		if(lines[i].t>k){
			dif[lines[i].u]++;
			dif[lines[i].v]++;
			dif[lines[i].lca]-=2;
			q[ed++]=i;
			overcot++;
		}
	}
	//cout<<"check_is_ok\n";
	check_dfs(1,0);
	//cout<<"check_dfs_is_ok\n";
	while(st<=ed){
		if(lines[q[st++]].t-maxdel>k){
			return 0;
		}
	}
	return 1;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<n;i++){
		int a,b,t;
		cin>>a>>b>>t;
		eg[a].push_back({b,t});
		eg[b].push_back({a,t});
	}
	DFS(1,0);
	if(db){
		for(int i=1;i<=cnt;i++)cout<<a[i]<<" ";
		cout<<"\n";
		for(int i=1;i<=n;i++)cout<<s[i]<<" "; 
		cout<<"\n";
		for(int i=1;i<=n;i++)cout<<deep[i]<<" "; 
		cout<<"\n";
	}
	buildST();
	if(db){
		for(int j=0;(1<<j)<=cnt;j++){
			for(int i=1;i+(1<<j)-1<=cnt;i++){
				cout<<st[i][j]<<" ";
			}
			cout<<'\n';
		}
	}
	for(int i=1;i<=m;i++){
		int u,v;
		cin>>u>>v;
		lines[i].u=u;
		lines[i].v=v;
		lines[i].lca=LCA(u,v);
		lines[i].t=deep[u]+deep[v]-2*(deep[lines[i].lca]);
	}
	if(db){
		for(int i=1;i<=m;i++){
			cout<<lines[i].u<<" ";
			cout<<lines[i].v<<" ";
			cout<<lines[i].lca<<" ";
			cout<<lines[i].t<<'\n';
		}
	}
	int l=0,r=MAXM;
	while(l<r){
		int mid=(l+r)>>1;
		if(check(mid))r=mid;
		else l=mid+1;
	}
	//cout<<"ef_ok\n";
	cout<<r<<endl;
	return 0;
}

预估的时间复杂度 O(nlogn+m)O(n\log n+m)

但是 mm 的常数会很大。

2025/1/24 13:10
加载中...