LCA+树上差分天天爱跑步
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LCA+树上差分天天爱跑步相关的知识,希望对你有一定的参考价值。
困扰我半年多的题终于做出来了
一开始我的做法是想在回溯的时候统计答案,但是各个分支之间又会相互影响,然后就不会做了
看完别人的题解后发现用桶的前后状态做差来统计答案更简单
1 #include <cstdio> 2 #include <vector> 3 #include <iostream> 4 #define db(x) cout<<#x<<"="<<x<<endl; 5 using namespace std; 6 const int N=300010; 7 typedef pair<int,int> P; 8 struct E{ 9 int next,to; 10 }e[2*N]; 11 int n,m,a,b,sz=0,head[N],w[N],dep[N],fa[N][20],chk1[3*N],chk2[3*N],ans[N]; 12 vector<int> p1[N],p2[N],q1[N],q2[N]; 13 void insert(int a,int b) 14 { 15 sz++; 16 e[sz].next=head[a]; 17 head[a]=sz; 18 e[sz].to=b; 19 } 20 void dfs(int x,int f) 21 { 22 for (int i=1;i<=19;i++) fa[x][i]=fa[fa[x][i-1]][i-1]; 23 for (int i=head[x];i;i=e[i].next) 24 if (e[i].to!=f) 25 { 26 dep[e[i].to]=dep[x]+1; 27 fa[e[i].to][0]=x; 28 dfs(e[i].to,x); 29 } 30 } 31 int lca(int a,int b) 32 { 33 if (dep[a]<dep[b]) swap(a,b); 34 int t=dep[a]-dep[b]; 35 for (int i=19;i>=0;i--) 36 if (t&(1<<i)) a=fa[a][i]; 37 for (int i=19;i>=0;i--) 38 if (fa[a][i]!=fa[b][i]) a=fa[a][i],b=fa[b][i]; 39 if (a==b) return a; 40 return fa[a][0]; 41 } 42 int solve(int x,int f) 43 { 44 int s=chk1[N+dep[x]+w[x]]+chk2[N+dep[x]-w[x]]; 45 for (int i=0;i<p1[x].size();i++) chk1[N+p1[x][i]]++; 46 for (int i=0;i<p2[x].size();i++) chk2[N+p2[x][i]]++; 47 for (int i=head[x];i;i=e[i].next) 48 if (e[i].to!=f) solve(e[i].to,x); 49 ans[x]+=chk1[N+dep[x]+w[x]]+chk2[N+dep[x]-w[x]]-s; 50 for (int i=0;i<q1[x].size();i++) chk1[N+q1[x][i]]--; 51 for (int i=0;i<q2[x].size();i++) chk2[N+q2[x][i]]--; 52 } 53 int main() 54 { 55 scanf("%d%d",&n,&m); 56 for (int i=1;i<n;i++) 57 { 58 scanf("%d%d",&a,&b); 59 insert(a,b);insert(b,a); 60 } 61 dfs(1,1); 62 for (int i=1;i<=n;i++) scanf("%d",&w[i]); 63 for (int i=1;i<=m;i++) 64 { 65 scanf("%d%d",&a,&b); 66 int s=lca(a,b); 67 if (w[s]==dep[a]-dep[s]) ans[s]--; 68 p1[a].push_back(dep[a]); 69 p2[b].push_back(-(dep[a]-2*dep[s])); 70 q1[s].push_back(dep[a]); 71 q2[s].push_back(-(dep[a]-2*dep[s])); 72 } 73 solve(1,1); 74 for (int i=1;i<=n;i++) printf("%d ",ans[i]); 75 }
以上是关于LCA+树上差分天天爱跑步的主要内容,如果未能解决你的问题,请参考以下文章