P4178 Tree Point Divide and Conquer

Idea: Divide and Conquer point

Submission: 1

answer:

Requirements weights and (\ leq K \) \ path, we can analogy template partition point , the length \ (len \) exists instead \ (len \) the number of paths, and with a tree like array maintenance and prefixes, so you can find the answer.

Code:

#include<bits/stdc++.h>
#define R register int
using namespace std;
namespace Luitaryi {
template<class I>   inline I g(I& x) { x=0; register I f=1;
    register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
    do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f;
} const int N=40010,Inf=1e9;
int n,m,cnt,tot,SZ,rt,sum,ans,K; bool vis[N];
int vr[N<<1],nxt[N<<1],w[N<<1],fir[N],d[N],sz[N],mx[N],dis[N],buf[N];
namespace BIT {
const int LIM=20000000;
int c[LIM+10];
inline void add(int p,int d) {for(;p<=LIM;p+=p&-p) c[p]+=d;}
inline int query(int p) { R ret=0;
    for(;p;p-=p&-p) ret+=c[p]; return ret;
}
}
inline void add(int u,int v,int ww) {
    vr[++cnt]=v,nxt[cnt]=fir[u],w[cnt]=ww,fir[u]=cnt;
    vr[++cnt]=u,nxt[cnt]=fir[v],w[cnt]=ww,fir[v]=cnt;
}
inline void getsz(int u,int fa) { 
    sz[u]=1,mx[u]=0; for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
        if(vis[v]||v==fa) continue;
        getsz(v,u),sz[u]+=sz[v];
        mx[u]=max(mx[u],sz[v]);
    } mx[u]=max(mx[u],sum-sz[u]);
    if(mx[u]<mx[rt]) rt=u;
}
inline void getdis(int u,int fa) { dis[++tot]=d[u];
    for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
        if(vis[v]||v==fa) continue;
        d[v]=d[u]+w[i],getdis(v,u);
    }
}
inline void solve(int u,int fa) { 
    SZ=0,BIT::add(1,1),buf[++SZ]=0,vis[u]=true;
    for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
        if(v==fa||vis[v]) continue;
        d[v]=w[i]; getdis(v,u);
        for(R k=1;k<=tot;++k) if(K>=dis[k]) ans+=BIT::query(K-dis[k]+1);
        for(R k=1;k<=tot;++k) buf[++SZ]=dis[k],BIT::add(dis[k]+1,1);
        tot=0;
    } while(SZ) BIT::add(buf[SZ]+1,-1),--SZ;
    for(R i=fir[u];i;i=nxt[i]) { R v=vr[i];
        if(v==fa||vis[v]) continue;
        sum=sz[v]; rt=0,mx[0]=Inf;
        getsz(v,u),getsz(rt,-1); solve(rt,u);
    }
}
inline void main() {
    g(n); for(R i=1,u,v,w;i<n;++i) g(u),g(v),g(w),add(u,v,w);
    g(K); sum=n,mx[0]=Inf; getsz(1,-1),getsz(rt,-1);
    solve(rt,-1); printf("%d\n",ans);
}
} signed main() {Luitaryi::main(); return 0;}

2019.08.31
69

Guess you like

Origin www.cnblogs.com/Jackpei/p/11437891.html