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;
}