P4292 [[WC2010] Reconstruction Plan]

P4292 [[WC2010] Reconstruction Plan]

Long chain split

The general idea of ​​score planning and long chain splitting has been explained very clearly by the big guys.
But I was too stunned by a problem for a long time. I
was how to allocate the space of the line segment tree corresponding to each subtree.

When we are processing the point x ,
first recursively process its great son, which is y,
and then directly let x inherit the data of y .

If the array corresponding to y is long like this,

we find that the point in the tree of y where
x is distance 1 is y The point x at a distance of 0 is a point at a distance of 2 is the point y is at a distance of 1 ... So this is obviously the dfs sequence formed by traversing the first son, where each long chain corresponds to a section




So this question is to build a line segment tree x subtree of the maximum weight of the point with a distance of n in the dfs sequence, corresponding to the dfn[x]+nth element in the line segment tree

I do not understand why I'm such a significant zhi ran zhang place cards for so long
the outermost layer of half a log segment tree a log
O (nlog the n-2) O (nlog ^ 2n)O ( n l o g2 n)
final code

#include <bits/stdc++.h>
#define N 100100
#define M 200100
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define mid ((l+r)>>1)
using namespace std;
typedef long long ll;
const double inf=-5e11*1.0;
int n,minn,maxx;
int f[N],nxt[M],data[M],num;
int dfn[N],mdep[N],dep[N],son[N],fa[N],len[N],root,ti;
double rr,mm,lst[N],far[M],dis[N];
int posi[N];
bool ans;
struct _tr{
    
    
	double t[N<<3];
	inline void push_up(int rt){
    
    
		t[rt]=max(t[rt<<1],t[rt<<1|1]);
	}
	inline void updata(int pos,double c,int rt=1,int l=1,int r=n){
    
    
		if(l==r){
    
     t[rt]=max(c,t[rt]); return; }
		if(pos<=mid){
    
     updata(pos,c,lson); }
		else{
    
     updata(pos,c,rson); }
		push_up(rt);
	}
	inline double query(int L,int R,int rt=1,int l=1,int r=n){
    
    
		if(L<=l&&r<=R)return t[rt];
		double res=inf;
		if(L<=mid)res=max(res,query(L,R,lson));
		if(R>mid)res=max(res,query(L,R,rson));
		return res;
	}
	inline void build(int rt=1,int l=1,int r=n){
    
    
		t[rt]=inf;
		if(l==r){
    
     posi[l]=rt; return; }
		build(lson); build(rson);
	}
}q;
void inline add(int x,int y,int z){
    
    
	nxt[++num]=f[x]; f[x]=num; data[num]=y; far[num]=z;
}
inline void dfs(int x){
    
    
	int y;
	for(int i=f[x];i;i=nxt[i]){
    
    
		y=data[i]; if(y==fa[x])continue;
		lst[y]=far[i];
		fa[y]=x; dep[y]=mdep[y]=dep[x]+1; dfs(y);
		if(mdep[x]<mdep[y]){
    
    
			son[x]=y; mdep[x]=mdep[y];
		}
	} 
	len[x]=mdep[x]-dep[x];
}
inline void dfs2(int x){
    
    
	dfn[x]=++ti;
	if(son[x]){
    
     dfs2(son[x]); }
	int y;
	for(int i=f[x];i;i=nxt[i]){
    
    
		y=data[i]; if(y==fa[x]||y==son[x])continue;
		dfs2(y);
	}
}
inline void solve(int x){
    
    
	int y=son[x],o=dfn[x],ql,qr,oo;
	double z;
	q.updata(o,dis[x]);
	if(y){
    
    
		dis[y]=dis[x]+lst[y]-mm;
		solve(y); if(ans==1)return;
	}
	for(int i=f[x];i;i=nxt[i]){
    
    
		y=data[i]; if(y==fa[x]||y==son[x])continue;
		dis[y]=dis[x]+lst[y]-mm; solve(y); if(ans==1)return;
		oo=dfn[y];
		for(int j=0;j<=min(maxx,len[y]);j++){
    
    
			ql=max(minn-1-j,0),qr=min(maxx-1-j,len[x]);
			if(ql>qr)continue;
			z=q.t[posi[oo+j]]-dis[x];
			if(q.query(o+ql,o+qr)-dis[x]+z>=0){
    
    
				ans=1; return; 
			}
		}
		for(int j=0;j<=min(len[y],maxx);j++){
    
    
			ql=1+j;
			if(q.t[posi[oo+j]]>q.t[posi[o+ql]]){
    
     q.updata(o+ql,q.t[posi[oo+j]]); }
		}
	}
	if(len[x]>=minn){
    
    
		if(q.query(o+minn,o+min(len[x],maxx))>=dis[x]){
    
    
			ans=1; return;
		}
	}
}

void get_ans(){
    
    
	double l=0,r=rr;
	while(r-l>0.0002){
    
    
		mm=(l+r)/2.0000;
		ans=0; dis[root]=0; q.build();
		solve(root);
		if(ans){
    
     l=mm; }
		else{
    
     r=mm; }
	} 
	printf("%.3lf",l);
}
int main(){
    
    
//	freopen("test.in","r",stdin);
	scanf("%d %d %d",&n,&minn,&maxx);
	int u,v,z;
	for(int i=1;i<n;i++){
    
    
		scanf("%d %d %d",&u,&v,&z);
		add(u,v,z); add(v,u,z); 
		rr=max((double)z,rr);
	}
	root=rand()%n+1;
	dfs(root); 
	dfs2(root); 
	get_ans();
	return 0;
} 

Guess you like

Origin blog.csdn.net/RA100FDM/article/details/109207084