Location>code7788 >text

P9058 [Ynoi2004] rpmtdq vs. P9678 [ICPC2022 Jinan R] Tree Distance

Popularity:879 ℃/2024-07-29 21:31:19

Thoughts:

Notice that point-to-point quantities have\(N^2\) individual, consider dropping some useless point pairs.

For point-to-point\((x_1,y_1),(x_2,y_2)\)fulfillment\(x_1 \le x_2 < y_2 \le y_1\)i.e., the interval\([x_2,y_2]\) (indicates passive-voice clauses)\([x_1,y_1]\) encompassAt this point, it would be a good idea to ask about the\([x_1,y_1]\)The first is to ask about the\([x_2,y_2]\)

if\(\operatorname{dis}(x_1,y_1) \ge \operatorname{dis}(x_2,y_2)\)Then at this point it is possible to set the\((x_1,y_1)\) abortThe reason is that if you want to use\((x_1,y_1\)) contribution, it would be better to go directly to the\((x_2,y_2)\) The contribution of, after all\((x_1,y_1)\) The contribution must be no less than that of the\((x_2,y_2)\) Better.

Then we can define if two points to\((x_1,y_1),(x_2,y_2)\) The following conditions are satisfied, then it is said that\((x_1,y_1)\) (indicates passive-voice clauses)\((x_2,y_2)\) control

  • \(x_1 \le x_2 < y_2 \le y_1\)

  • \(\operatorname{dis}(x_1,y_1) \ge \operatorname{dis}(x_2,y_2)\)

At this point define apairs of dominant pointsSatisfying the fact that no point has been made by any of thecontrol, i.e., we need to find all thepairs of dominant pointsto calculate the contribution.

Noting that it is a point-to-distance problem on a tree, considerpartitionSolution.

currentlycenter of gravitybecause of\(rt\)For points\(v\)warrant\(S_v\) Indicates that the current connectivity block in thepossessfulfillment\(\operatorname{dis}(i,rt) \le \operatorname{dis}(v,rt)\) (used form a nominal expression)\(i\) composed of aset (mathematics)

Then it can be used in conjunction with\(v\) make uppairs of dominant pointsThe point of must be\(S_v\) center\(v\) (used form a nominal expression)front drivecap (a poem)successornamely\(S_v\) center\(<v\) centerlargest numbercap (a poem)\(>v\) centerleast significant number

Simply testify that the setup\(S_v\) center\(v\) (used form a nominal expression)front drivebecause of\(u\)

  • there are\(\operatorname{dis}(i,u) \le \operatorname{dis}(i,rt) + \operatorname{dis}(u,rt) \le \operatorname{dis}(i,rt) + \operatorname{dis}(v,rt) = \operatorname{dis}(i,v)\)namely\(\operatorname{dis}(i,u) \le \operatorname{dis}(i,v)\)

  • Noting that at this time\(i < u < v\) maybe\(u < v < i\)namely\((i,v)\) (indicates passive-voice clauses)\((i,u)\) controlmaybe\((u,i)\) (indicates passive-voice clauses)\((v,i)\) control

  • Then only if\(i=u\) when\((u,u)\) point-to-pointnon-existent\((u,v)\) It will not be used by other\(S_v\) Point-to-point domination in the middle.

successorThe situation is similar, so I won't go into it.

Then consider how quickly you can findpairs of dominant pointsIf you're looking for it, you can find it directly by following the method above.\(S_v\)The complexity must be\(O(N^2)\) For starters, consider optimization.

First for all the points in the entire connectivity block, according to the points'serial numberSort the order ascending and then maintain a\(\operatorname{dis}(i,rt)\) freemonotonic stack

Then there is the property that for the point being\(i\) bounce\(u\)I'm sure you'll be satisfied.\(i\) be\(u\) offsidefirstless than or equal to\(\operatorname{dis}(u,rt)\) of the point and minimizes the number, i.e.\(i\) be\(S_u\) center\(u\) (used form a nominal expression)front driveThen do it again in reverse descending ordermonotonic stackcall on sb.successorReady to go.

At this point let's estimatepairs of dominant pointsThe number of points, each of which will be recognized by at most\(\log N\) classifier for individual things or people, general, catch-all classifiercenter of gravity of partitionContains, each containment adds up to\(2\) treat (sb a certain way)pairs of dominant pointsi.e., totalpairs of dominant pointsThe number of\(N \log N\) Around.

Now having solved for the fullpairs of dominant points, i.e., there are contributing pairs of points, now consider how to find the interval being aembodyallpairs of dominant pointsThe minimum contribution value of can be used onlineone tree fits anotherBut it's not necessary.

Consider offline usescanning lineAlgorithm, since tree arrays are not good at maintaining suffix minima, consider sweeping the left endpoints backwards, and then for each pair of points, adding the right endpoint contribution at the left endpoint; then for a query at the left endpoint, it is a prefix minimum.

The time complexity is\(O(N \log^2 N + Q \log N)\)

Full Code:

#include<bits/stdc++.h>
#define Add(x,y) (x+y>=mod)?(x+y-mod):(x+y)
#define lowbit(x) x&(-x)
#define full(l,r,x) for(auto it=l;it!=r;it++) (*it)=x
#define Full(a) memset(a,0,sizeof(a))
#define open(s1,s2) freopen(s1,"r",stdin),freopen(s2,"w",stdout);
using namespace std;
typedef double db;
typedef unsigned long long ull;
typedef long long ll;
const ll N=2e5+10,M=1e6+10,INF=1e18; 
bool Begin;
inline ll read(){
    ll x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')
          f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=(x<<1)+(x<<3)+(c^48);
        c=getchar();
    }
    return x*f;
}
inline void write(ll x){
	if(x<0){
		putchar('-');
		x=-x;
	}
	if(x>9)
	  write(x/10);
	putchar(x%10+'0');
}
int n,q;
ll ans[M];
vector<int> G[N];
vector<pair<int,ll>> E[N],Q[N];
void add(int u,int v,int w){
	E[u].push_back({v,w});
	E[v].push_back({u,w});
}
namespace Lowbit{
	ll a[N];
	inline void init(){
		for(int i=1;i<=n;i++)
		  a[i]=INF;
	}
	inline void add(int x,ll w){
		for(int i=x;i<=n;i+=lowbit(i))
		  a[i]=min(a[i],w);
	}
	inline ll query(int x){
		ll ans=INF;
		for(int i=x;i;i-=lowbit(i))
		  ans=min(ans,a[i]);
		return ans;
	}	
};
namespace LCA{
	int p[N],t[N],z[N],d[N],fa[N];
	ll dep[N];
	inline void dfs1(int u,int f){
		p[u]=1;
		for(auto t:E[u]){
			int v=,w=;
			if(v==f)
			  continue;
			dep[v]=dep[u]+w;
			d[v]=d[u]+1;
			fa[v]=u;
			dfs1(v,u);
			p[u]+=p[v];
			if(p[v]>p[z[u]])
			  z[u]=v;
		}
	}
	inline void dfs2(int u,int k){
		t[u]=k;
		if(!z[u])
		  return ;
		dfs2(z[u],k);
		for(auto t:E[u]){
			int v=;
			if(v==fa[u]||v==z[u])
			  continue;
			dfs2(v,v);
		}
	}
	inline int Lca(int u,int v){
		while(t[u]!=t[v]){
			if(d[t[u]]<d[t[v]])
			  swap(u,v);
			u=fa[t[u]];
		}
		return d[u]<d[v]?u:v;
	}
	inline ll dis(int u,int v){
		return dep[u]+dep[v]-(dep[Lca(u,v)]<<1ll);
	}
	inline void init(){
		dfs1(1,1);
		dfs2(1,1);
	}
};
namespace Tree{
	int sum,cnt,top,Max,root;
	int T[N],siz[N];
	pair<int,ll> dis[N];
	bool del[N];
	inline void add(int x,int y){
		if(x>y)
		  swap(x,y);
		G[x].push_back(y);
	}
	inline void getroot(int u,int fa){
		int s=0;
		siz[u]=1;
		for(auto t:E[u]){
			ll v=;
			if(del[v]||v==fa)
			  continue;
			getroot(v,u);
			siz[u]+=siz[v];
			s=max(s,siz[v]);
		}
		s=max(s,sum-siz[u]);
		if(s<Max){
			Max=s;
			root=u;
		}
	}
	inline void Get(int u,int p){
		root=0;
		sum=Max=p;
		getroot(u,0);
		getroot(root,0);
	}
	inline void getdis(int u,int fa,ll d){
		dis[++cnt]={u,d};
		for(auto t:E[u]){
			int v=,w=;
			if(v==fa||del[v])
			  continue;
			getdis(v,u,d+w);
		}
	}
	inline void calc(int u){
		cnt=0;
		getdis(u,0,0);
		sort(dis+1,dis+cnt+1);
		top=0;
		for(int i=1;i<=cnt;i++){
			while(top&&dis[i].second<=dis[T[top]].second){
				add(dis[i].first,dis[T[top]].first);
				top--;
			}
			T[++top]=i;
		}
		top=0;
		for(int i=cnt;i>=1;i--){
			while(top&&dis[i].second<=dis[T[top]].second){
				add(dis[i].first,dis[T[top]].first);
				top--;
			}
			T[++top]=i;			
		}
	}
	inline void solve(int u){
		calc(u);
		del[u]=1;
		for(auto t:E[u]){
			int v=;
			if(del[v])
			  continue;
			Get(v,siz[v]);
			solve(root);
		}
	}	
	void work(){
		Lowbit::init();
		LCA::init();
		Get(1,n);
		solve(root);
	}
};
bool End;
int main(){
//	open("","");
	n=read();
	for(int u,v,w,i=1;i<n;i++){
		u=read(),v=read(),w=read();
		add(u,v,w); 
	}
	q=read();
	for(int l,r,i=1;i<=q;i++){
		l=read(),r=read();
		Q[l].push_back({i,r});
	}
	Tree::work();
	for(int i=n;i>=1;i--){
		for(auto v:G[i])
		  Lowbit::add(v,LCA::dis(i,v));
		for(auto t:Q[i])
		  ans[]=Lowbit::query();
	}
	for(int i=1;i<=q;i++){
		write(ans[i]==INF?-1:ans[i]);
		putchar('\n');
	}
	cerr<<'\n'<<abs(&Begin-&End)/1048576<<"MB";
	return 0;
}