题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5293
被这题打蹦了,看着题解写的,很是爆炸,确实想不到,我用的DFS序+LCA+树形DP,当然也可以写树剖,不过这里DFS序更简单,因为都是对点到根的操作
#include
#include
#include
#pragma comment(linker, "/STACK:102400000,102400000")
#define F(i,a,b) for(int i=a;i<=b;i++)
#define root 1,n,1
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
using namespace std;
const int N=1e5+7,DEG=20;
int t,n,m,x,y,dp[N],sum[N],c1[N*2],c2[N*2];
struct edge{int u,v,w,lca;}p[N];
vectorvec[N];
inline void add(int x,int k,int *c){for(;x<=n*2;x+=x&-x)c[x]+=k;}
inline int ask(int x,int *c){int an=0;while(x)an+=c[x],x-=x&-x;return an;}
//LCA+dfs序
int ed,g[N],nxt[2*N],v[2*N],fa[N][DEG],dep[N],idx,l[2*N],r[2*N];
inline void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
void LCA_dfs(int u,int pre){
dep[u]=dep[pre]+1,fa[u][0]=pre,l[u]=++idx;
F(i,1,DEG-1)fa[u][i]=fa[fa[u][i-1]][i-1];
for(int i=g[u];~i;i=nxt[i])if(v[i]!=pre)LCA_dfs(v[i],u);
r[u]=++idx;
}
int LCA(int a,int b){
if(dep[a]>dep[b])a^=b,b^=a,a^=b;
if(dep[a]=0;i--)
if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
return a;
}
void fuck(int s,int fa){
dp[s]=sum[s]=0;
for(int i=g[s];~i;i=nxt[i])if(v[i]!=fa)fuck(v[i],s),sum[s]+=dp[v[i]];
dp[s]=sum[s];
for(int i=0;i