树剖实现加减,60pts求调或小数据hank,悬关
查看原帖
树剖实现加减,60pts求调或小数据hank,悬关
484751
ssl_lwz楼主2024/8/24 16:12

rt

#include<bits/stdc++.h>
#define int long long
#define ls p<<1
#define rs p<<1|1
using namespace std;

const int N = 1e6 + 10;
int bval[N];
int n,m,siz[N],tot,son[N],dfn[N],dep[N],top[N],dis[N],fa[N],vl[N];
struct node{
	int y,val;
};
vector<node> v[N];
pair<int,int> d[N],tr[N];
int cnt;
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){
	    if(ch=='-')  f=-1;
	    ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
	    x=x*10+ch-48;
	    ch=getchar();
    }
    return x*f;
}
void dfs1(int p,int f,int deep){
	dep[p]=deep;fa[p]=f;
	son[p]=-1;
	for(node t:v[p]){
		if(t.y==f)  continue;
		dis[t.y]=dis[p]+t.val;
		dfs1(t.y,p,deep+1);
		siz[p]+=siz[t.y];
		if(son[p]==-1||siz[t.y]>siz[son[p]])  
		  son[p]=t.y;
	}
}
void dfs2(int p,int topf){
	dfn[p]=++tot;top[p]=topf;
	if(son[p]==-1)  return;
	dfs2(son[p],topf);
	for(node t:v[p]){
		if(t.y==fa[p]||son[p]==t.y)  continue;
		dfs2(t.y,t.y);
	}
}
int lca(int x,int y){
	while(top[x]!=top[y]){
		if(dep[top[x]]>dep[top[y]])  x=fa[top[x]];
		else y=fa[top[y]];
	}
	return dep[x]<dep[y]?x:y;
}
int cal(int x,int y){
	return dis[x]+dis[y]-2*dis[lca(x,y)];
}
struct SEG{
    int sum[N<<2],tag[N<<2];
    void up(int p){
    	sum[p]=sum[ls]+sum[rs];
	}
	void push_d(int p,int l,int r){
		if(tag[p]){
			int mid=l+r>>1;
			tag[ls]+=tag[p];
			tag[rs]+=tag[p];
			sum[ls]+=tag[p]*(mid-l+1);
			sum[rs]+=tag[p]*(r-mid);
		}
	}
	void upd(int p,int l,int r,int x,int y,int k){
		if(x<=l&&r<=y){
			sum[p]+=(r-l+1)*k;
			tag[p]+=k;
			return; 
		}
		if(l>y||r<x)  return;
		push_d(p,l,r);int mid=l+r>>1;
		if(x<=mid)  upd(ls,l,mid,x,y,k);
		if(y>mid)  upd(rs,mid+1,r,x,y,k);
		up(p);
	}
	int query(int p,int l,int r,int x,int y){
		if(x<=l&&r<=y)  return sum[p];
		if(l>y||r<x)  return 0;
		push_d(p,l,r);int mid=l+r>>1,res=0;
		if(x<=mid)  res+=query(ls,l,mid,x,y);
		if(y>mid)  res+=query(rs,mid+1,r,x,y);
		return res;
	}
}st;
int ser_sum(int x,int y){
	int res=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])  swap(x,y);
		res+=st.query(1,1,n,dfn[top[x]],dfn[x]);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])   swap(x,y);
	if(x!=y)  res+=st.query(1,1,n,dfn[x]+1,dfn[y]);
	return res;
}
void upd_range(int x,int y,int k){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])  swap(x,y);
		st.upd(1,1,n,dfn[top[x]],dfn[x],k);
		x=fa[top[x]];
	} 
	if(dep[x]>dep[y])  swap(x,y);
	if(x!=y)  st.upd(1,1,n,dfn[x]+1,dfn[y],k);
}
bool chk(int x){  //要求该时间<=x 
    bool fs=true;int maxn=0;
	for(int i=1;i<=m;i++){
	//	cout<<val[i]<<"CCf"<<endl;
		if(vl[i]>x){
			fs=false;maxn=max(maxn,vl[i]);
		    upd_range(d[i].first,d[i].second,1);
		}  
	}
	if(fs){return true;}
	fs=false; 
	for(int i=1;i<n;i++){
		int p=ser_sum(tr[i].first,tr[i].second);
		if(p==cnt&&maxn-bval[i]<=x){
			fs=true;
			break;
		}
	}
	memset(st.tag,0,sizeof st.tag);memset(st.sum,0,sizeof st.sum);
	return fs;
}
void solve(){
	for(int i=1,x,y;i<=m;i++){
		x=read();y=read();d[i]={x,y};
		vl[i]=cal(x,y);
	}
	sort(vl+1,vl+m+1);	
	int l=0,r=vl[m]+10000;
	while(l<r){
		int mid=(l+r)/2;
		if(chk(mid))  r=mid;
		else l=mid+1;
	}
	cout<<r;
}
signed main(){
	ios::sync_with_stdio(0);cout.tie(0); 
	n=read();m=read();
	for(int i=1,x,y,w;i<n;++i){
		x=read();y=read();w=read();
		v[x].push_back({y,w});
		v[y].push_back({x,w});
		tr[i]={x,y};bval[i]=w;
	}
	dfs1(1,0,1);dfs2(1,0);
	solve();
	return 0;
}
2024/8/24 16:12
加载中...