BZOJ - 3631 松鼠的新家 (树链剖分)

题目链接

树链剖分基础题,路径权值修改+差分

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=3e5+10;
 5 int hd[N],ne,n,m,a[N],fa[N],son[N],dep[N],siz[N],top[N],dfn[N],rnk[N],tot,c[N];
 6 struct E {int v,nxt;} e[N<<1];
 7 void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;}
 8 void dfs1(int u,int f,int d) {
 9     fa[u]=f,son[u]=0,dep[u]=d,siz[u]=1;
10     for(int i=hd[u]; ~i; i=e[i].nxt) {
11         int v=e[i].v;
12         if(v==fa[u])continue;
13         dfs1(v,u,d+1),siz[u]+=siz[v];
14         if(siz[v]>siz[son[u]])son[u]=v;
15     }
16 }
17 void dfs2(int u,int tp) {
18     top[u]=tp,dfn[u]=++tot,rnk[dfn[u]]=u;
19     if(!son[u])return;
20     dfs2(son[u],top[u]);
21     for(int i=hd[u]; ~i; i=e[i].nxt) {
22         int v=e[i].v;
23         if(v==fa[u]||v==son[u])continue;
24         dfs2(v,v);
25     }
26 }
27 void upd(int u,int v) {
28     for(; top[u]!=top[v]; u=fa[top[u]]) {
29         if(dep[top[u]]<dep[top[v]])swap(u,v);
30         c[dfn[top[u]]]++,c[dfn[u]+1]--;
31     }
32     if(dep[u]<dep[v])swap(u,v);
33     c[dfn[v]]++,c[dfn[u]+1]--;
34 }
35 
36 int main() {
37     memset(hd,-1,sizeof hd),ne=0;
38     scanf("%d",&n);
39     for(int i=0; i<n; ++i)scanf("%d",&a[i]);
40     for(int i=1; i<n; ++i) {
41         int u,v;
42         scanf("%d%d",&u,&v);
43         addedge(u,v);
44         addedge(v,u);
45     }
46     tot=0,dfs1(1,0,0),dfs2(1,1);
47     for(int i=0; i<n-1; ++i)upd(a[i],a[i+1]);
48     for(int i=1; i<=tot; ++i)c[i]+=c[i-1];
49     for(int i=1; i<n; ++i)c[dfn[a[i]]]--;
50     for(int i=1; i<=n; ++i)printf("%d\n",c[dfn[i]]);
51     return 0;
52 }

 

posted @ 2019-03-23 14:52  jrltx  阅读(116)  评论(0编辑  收藏  举报