UOJ 261/bzoj 4719(LCA)(NOIP2016)(天天爱跑步)
来源:互联网 发布:手机淘宝怎么看评价 编辑:程序博客网 时间:2024/05/29 15:10
传送门
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[N],etot=0;struct EDGE { int v,nxt;}e[N<<1];int w[N],ans[N],f[21][N],dep[N],t[N<<1],g[N<<1],mark[N];vector<int > c1[N],c2[N],c3[N];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;}
阅读全文
0 0
- UOJ 261/bzoj 4719(LCA)(NOIP2016)(天天爱跑步)
- 【LCA+打标记】BZOJ4719(UOJ#261) [Noip2016]天天爱跑步
- UOJ261 NOIP2016 day1 T2 天天爱跑步 (lca + 桶 )
- NOIP2016 天天爱跑步 (LCA,树上差分)
- [BZOJ]4719: [Noip2016]天天爱跑步 LCA+奇技淫巧
- 【BZOJ】4719 [Noip2016]天天爱跑步 LCA+树上差分
- NOIP2016天天爱跑步(洛谷1600)
- 【bzoj 4719】[Noip2016]天天爱跑步
- BZOJ 4719: [Noip2016]天天爱跑步 tarjanlca
- [NOIP2016] 天天爱跑步 (LCA+线段树(动态开点)+差分+dfs序)
- noip2016 Day1 T2:天天爱跑步(Lca+树上差分)
- NOIP2016提高组D1T2天天爱跑步(lca+树上差分)
- bzoj4719 [Noip2016]天天爱跑步(树+lca+树上差分+思路题)
- 【BzoJ 4719】【Noip2016】【天天爱跑步】【lca】【方程移项】【桶排优化】
- [NOIP2016]天天爱跑步(lca+乱搞)
- Noip2016 天天爱跑步【LCA】【差分】
- BZOJ4719(NOIP2016)[天天爱跑步]--LCA+DFS
- 洛谷P1600 天天爱跑步(NOIp2016)(BZOJ4719)
- 什么是闭包?
- eclipse中.svg文件报错
- hive分区表增加字段会导致新增字段无法显示值的BUG
- java环境配置
- PHP中magic_quotes_gpc和 magic_quotes_runtime区别
- UOJ 261/bzoj 4719(LCA)(NOIP2016)(天天爱跑步)
- antlr-2.7.6.jar 包问题
- 视频监控安防平台-国标28181 2016-GB28181 2016版检测经历 (平台上联和下联检测)
- 好未来面试问题整理
- 身边最牛逼的程序员是不是都是这个样子的?
- Android 外边框
- Spring入门(基于Java的容器注解之@ImportResource和@Value)
- Log4j使用(一):每天生成一个日志文件DailyRollingFileAppender的使用
- 当鼠标拖曳事件碰到iframe(卡死了)