UOJ 261/bzoj 4719(LCA)(NOIP2016)(天天爱跑步)
2017-09-29 17:35
477 查看
传送门
NOIP 2016 D1T2
题解请参考:https://www.cnblogs.com/Yuzao/p/6918931.html
大概就是讨论出两种情况:
1.dep[q[i].st]=dep[u]+w[u]
2.dep[q[i].ed]-q[i].len=dep[u]-w[u]
然后用桶来记录值域,dfs两遍统计合法的贡献(子树内?子树外?),最后对于位于LCA的位置去重(两种情况都计算了它)即可。
NOIP 2016 D1T2
题解请参考:https://www.cnblogs.com/Yuzao/p/6918931.html
大概就是讨论出两种情况:
1.dep[q[i].st]=dep[u]+w[u]
2.dep[q[i].ed]-q[i].len=dep[u]-w[u]
然后用桶来记录值域,dfs两遍统计合法的贡献(子树内?子树外?),最后对于位于LCA的位置去重(两种情况都计算了它)即可。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector> using namespace std; const int N=3e5+4,M=3e5+4; int n,m,head ,etot=0; struct EDGE { int v,nxt; }e[N<<1]; int w ,ans ,f[21] ,dep ,t[N<<1],g[N<<1],mark ; vector<int > c1 ,c2 ,c3 ; struct Node { int st,ed,len,lca; }q[M]; inline int read() { int x=0;char c=getchar(); while (c<'0'||c>'9') c=getchar(); while (c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar(); return x; } inline void adde(int u,int v) { e[etot].nxt=head[u],e[etot].v=v,head[u]=etot++; e[etot].nxt=head[v],e[etot].v=u,head[v]=etot++; } void pre_dfs(int p,int fa) { f[0][p]=fa,dep[p]=dep[fa]+1; for (int j=1;j<21;++j) f[j][p]=f[j-1][f[j-1][p]]; for (int i=head[p];~i;i=e[i].nxt) { int v=e[i].v; if (v^fa) pre_dfs(v,p); } } inline int qlca(int x,int y) { if (dep[x]<dep[y]) x^=y^=x^=y; int t=dep[x]-dep[y]; for (int i=0;i<21;++i) if (t&(1<<i)) x=f[i][x]; if (x==y) return x; for (int i=20;~i;--i) if (f[i][x]^f[i][y]) x=f[i][x],y=f[i][y]; return f[0][x]; } void dfs1(int p,int fa) { int now=dep[p]+w[p],pre=t[now]; for (int i=head[p];~i;i=e[i].nxt) { int v=e[i].v; if (v^fa) dfs1(v,p); } t[dep[p]]+=mark[p]; ans[p]+=t[now]-pre; for (int i=0;i<c1[p].size();++i) --t[c1[p][i]]; } void dfs2(int p,int fa) { int now=dep[p]-w[p]+N,pre=g[now]; for (int i=head[p];~i;i=e[i].nxt) { int v=e[i].v; if (v^fa) dfs2(v,p); } for (int i=0;i<c2[p].size();++i) ++g[c2[p][i]]; ans[p]+=g[now]-pre; for (int i=0;i<c3[p].size();++i) --g[c3[p][i]]; } int main() { // freopen("UOJ 261.in","r",stdin); memset(head,-1,sizeof(head)); n=read(),m=read(); for (register int i=1;i<n;++i) { int u=read(),v=read(); adde(u,v); } pre_dfs(1,0); for (register int i=1;i<=n;++i) w[i]=read(); for (register int i=1;i<=m;++i) { q[i].st=read(),q[i].ed=read(); q[i].lca=qlca(q[i].st,q[i].ed),q[i].len=dep[q[i].st]+dep[q[i].ed]-(dep[q[i].lca]<<1); } for (register int i=1;i<=m;++i) { ++mark[q[i].st]; c1[q[i].lca].push_back(dep[q[i].st]); } dfs1(1,0); for (register int i=1;i<=m;++i) { c2[q[i].ed].push_back(dep[q[i].ed]-q[i].len+N); c3[q[i].lca].push_back(dep[q[i].ed]-q[i].len+N); } dfs2(1,0); for (register int i=1;i<=m;++i) if (dep[q[i].st]==dep[q[i].lca]+w[q[i].lca]) --ans[q[i].lca]; for (register int i=1;i<=n;++i) printf("%d ",ans[i]); return 0; }
相关文章推荐
- NOIP2016 day1T2--BZOJ4719 天天爱跑步--LCA+差分
- 【BzoJ 4719】【Noip2016】【天天爱跑步】【lca】【方程移项】【桶排优化】
- UOJ261 NOIP2016 day1 T2 天天爱跑步 (lca + 桶 )
- [BZOJ]4719: [Noip2016]天天爱跑步 LCA+奇技淫巧
- BZOJ 4719: [Noip2016]天天爱跑步 tarjanlca
- 【BZOJ】4719 [Noip2016]天天爱跑步 LCA+树上差分
- bzoj 4719: [Noip2016]天天爱跑步【树上差分+dfs】
- [UOJ261]天天爱跑步
- bzoj4719 [Noip2016]天天爱跑步
- BZOJ 4719 [Noip2016]天天爱跑步 ——树链剖分
- 【bzoj4719】[Noip2016]天天爱跑步
- bzoj 4719: [Noip2016]天天爱跑步
- NOIP 2016 天天爱跑步 (luogu 1600 & uoj 261) - 线段树
- [BZOJ4719][Noip2016]天天爱跑步
- NOIP2016 天天爱跑步 (LCA,树上差分)
- [bzoj4719][树链剖分][Noip2016]天天爱跑步
- BZOJ4719(NOIP2016)[天天爱跑步]--LCA+DFS
- bzoj 4719: [Noip2016]天天爱跑步 线段树合并
- [UOJ] #261 天天爱跑步
- 【NOIP2016】bzoj4719 天天爱跑步