Codeforces Round #294 (Div. 2) E
来源:互联网 发布:win7 for mac 安装iso 编辑:程序博客网 时间:2024/05/18 23:12
题目大意:给你一棵有n个节点的树。再给你m个询问,每次询问A,B。问你树上到A,B距离相等的点有几个。
这场DIV2为何这么水 = =而且我竟然没报名参赛。。。
这题直接用倍增LCA即可
用son[]表示子节点个数
求出A B的链长度
然后求出链的中点X
这里分类讨论一下
dep[A]==dep[B]
ans=n-A跳到X的子树-B跳到X的子树
dep[A]!=dep[B]
ans=son[x]-B跳到X的子树
然后就弄完了
#include<queue>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;struct line{ int s,t; int next;}a[1000001];int head[500001];int edge;inline void add(int s,int t){ a[edge].next=head[s]; head[s]=edge; a[edge].s=s; a[edge].t=t;}bool v[500001];int deep[500001];int ans[500001][22];inline void bfs(int r){ int i,j; deep[r]=1; for(i=0;i<=21;i++) ans[r][i]=r; queue <int>Q; while(!Q.empty()) Q.pop(); Q.push(r); v[r]=true; while(!Q.empty()) { int d=Q.front(); Q.pop(); for(i=head[d];i!=0;i=a[i].next) { int t=a[i].t; if(!v[t]) { v[t]=true; Q.push(t); deep[t]=deep[d]+1; ans[t][0]=d; int dt;long long dc; for(j=1;j<=21;j++) { dt=ans[t][j-1]; ans[t][j]=ans[dt][j-1]; } } } }}int son[100001];inline void dfs(int d){ int i; for(i=head[d];i!=0;i=a[i].next) { int t=a[i].t; if(t!=ans[d][0]) { dfs(t); son[d]+=son[t]; } } son[d]++;}inline int swim(int x,int y){ while(deep[x]!=deep[y]) { int i=0; while(deep[ans[y][i]]>deep[x]) i++; if(i!=0) i--; y=ans[y][i]; } return y;}inline int swimx(int x,int y){ int i=1; for(int pt=1;pt<=22;pt++) i=i*2; int pt=22; while(x!=0) { while(i>x) { i/=2; pt--; } y=ans[y][pt]; x-=i; } return y;}inline int lca(int x,int y){ if(deep[x]>deep[y]) { int t=x; x=y; y=t; } y=swim(x,y); int i=21; while(x!=y) { while(ans[x][i]==ans[y][i]&&i>0) i--; x=ans[x][i]; y=ans[y][i]; } return x;}int fa[100001];inline int find(int x){ if(fa[x]!=x) fa[x]=find(fa[x]); return fa[x];}int main(){ int n,m; scanf("%d",&n); int i,s,t; for(i=1;i<=n-1;i++) { scanf("%d%d",&s,&t); edge++; add(s,t); edge++; add(t,s); } bfs(1); dfs(1); scanf("%d",&m); for(i=1;i<=m;i++) { scanf("%d%d",&s,&t); if(s==t) printf("%d\n",n); else { if(deep[s]>deep[t]) { int xt=s; s=t; t=xt; } int tx=lca(s,t); int len=0; if(tx==s) len=deep[t]-deep[s]; else len=deep[s]-deep[tx]+deep[t]-deep[tx]; if(len%2==1) printf("0\n"); else if(deep[s]!=deep[t]) { int yy=swimx(len/2-1,t); int anst=son[ans[yy][0]]-son[yy]; printf("%d\n",anst); } else if(deep[s]==deep[t]) { int yy=swimx(len/2-1,t); int xx=swimx(len/2-1,s); int anst=n-son[yy]-son[xx]; printf("%d\n",anst); } } } return 0;}
0 0
- Codeforces Round #294 (Div. 2) E
- Codeforces Round #294 (Div.2) E Shaass the Great
- Codeforces Round #294 (Div. 2) (C D E)
- Codeforces Round #294 (Div. 2) E 树上倍增lca
- Codeforces Round #294 (Div. 2) E LCA倍增
- Codeforces 405E Codeforces Round #238 (Div. 2)E
- Codeforces Round #103 (Div. 2) E题
- Codeforces Round #147 (Div. 2) E
- Codeforces Round #184 (Div. 2) D、E
- Codeforces Round #197 (Div. 2) (C~E)
- Codeforces Round #102 (Div. 2) //缺E
- Codeforces Round #104 (Div. 2) //缺E
- Codeforces Round #105 (Div. 2) //缺E
- Codeforces Round #103 (Div. 2) //缺E
- Codeforces Round #106 (Div. 2) //缺E
- Codeforces Round #223 (Div. 2) E
- Codeforces Round #229 (Div. 2) E
- Codeforces Round #139 (Div. 2) E. Unsolvable
- Spring bean的作用域
- 在android中实现DES加密
- 最爱的城市
- #294 (div.2) E.A and B and Lecture Rooms
- 小控件集合
- Codeforces Round #294 (Div. 2) E
- 解决ADT和SDK版本不一致问题
- Cocos2d-x 3.2 onEnter与onEnterTransitionDidFinish的区别
- struct/class/union内存对齐原则
- Python的platform模块
- python 赋值的时候是引用,如果需要复制则需要注意深拷贝和浅拷贝的区别
- OC--简单的ATM算法
- java AES 加解密代码
- iOS内存管理