【Codeforces418D】Big Problems for Organizers
来源:互联网 发布:数据有效性wps2016 编辑:程序博客网 时间:2024/06/11 16:42
先求出树的直径。
预处理出直径,用
询问时,先找到
1、直径两端点的答案
2、
#include <bits/stdc++.h>#define gc getchar()#define ll long long#define mid (l+r>>1)#define N 100009using namespace std;int n,Q,first[N],number,root[N],fa[N],dis[N],f[N][20],g[N][20],bit[20],lg[N],X,Y;struct edge{ int to,next; void add(int x,int y) { to=y,next=first[x],first[x]=number; }}e[N<<1];int read(){ int x=1; char ch; while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1; int s=ch-'0'; while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0'; return s*x;}int bfs(int x,int from){ int ret=0; queue<int> q; while (!q.empty()) q.pop(); dis[x]=0,root[x]=from,fa[x]=from; q.push(x); while (!q.empty()) { int now=q.front(); q.pop(); if (dis[ret]<dis[now]) ret=now; for (int i=first[now];i;i=e[i].next) if (e[i].to!=fa[now]) { dis[e[i].to]=dis[now]+1,root[e[i].to]=from,fa[e[i].to]=now; q.push(e[i].to); } } return ret;}int rmq(int f[][20],int x,int y){ if (x>y) return 0; int k=lg[y-x+1]; return max(f[x][k],f[y-bit[k]+1][k]);}void init(){ //ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0); bit[0]=1; for (int i=1;i<20;i++) bit[i]=bit[i-1]<<1; lg[0]=-1; for (int i=1;i<N;i++) lg[i]=lg[i>>1]+1; n=read(); for (int i=1;i<n;i++) { int x=read(),y=read(); e[++number].add(x,y),e[++number].add(y,x); } int x=bfs(1,0); int y=bfs(x,0); for (int i=y,j=0;i;j=i,i=fa[i]) { int Max=0; root[i]=i; for (int k=first[i];k;k=e[k].next) if (e[k].to!=fa[i]&&e[k].to!=j) Max=max(Max,dis[bfs(e[k].to,i)]+1); f[dis[i]][0]=Max+dis[i]; g[dis[i]][0]=Max+dis[y]-dis[i]; } for (int i=1;i<20;i++) for (int j=1;j+bit[i]-1<=dis[y];j++) { f[j][i]=max(f[j][i-1],f[j+bit[i-1]][i-1]); g[j][i]=max(g[j][i-1],g[j+bit[i-1]][i-1]); } X=x,Y=y;}void work(){ Q=read(); while (Q--) { int x=read(),y=read(); int l=dis[root[x]],r=dis[root[y]]; if (l<r) swap(l,r),swap(x,y); int dx=0,dy=0; if (x!=root[x]) l+=dis[x]+1,dx=dis[x]+1,x=root[x]; if (y!=root[y]) r-=dis[y]+1,dy=dis[y]+1,y=root[y]; int ret=min(dx+dis[Y]-dis[x],dy+dis[Y]-dis[y]); ret=max(ret,min(dx+dis[x],dy+dis[y])); ret=max(ret,rmq(f,dis[y]+1,min(mid,dis[x]))-r); ret=max(ret,rmq(g,max(mid+1,dis[y]),dis[x]-1)-(dis[Y]-l)); printf("%d\n",ret); }}int main(){ init(); work(); return 0;}
阅读全文
0 0
- Codeforces418D Big Problems for Organizers
- 【Codeforces418D】Big Problems for Organizers
- 【jzoj3824】【codeforces RCC 2014 Warmup (Div. 1) D】【Big Problems for Organizers】【树】
- Problems for Beginners
- Problems for Round
- Matlab Builder for java problems
- SAS programming for spatial problems
- python implement for selected problems
- linux command solution for problems
- codeforce之problems for round
- Big Data : Analysis of problems with traditional architecture
- Apache Spark for Big Analytics
- infographic tech for big data
- Big Data, AI for 保险。。。
- Tips for solving CSS problems in IE7
- Common Problems (and Their Solutions) for java
- Problems About Rearrangement for Expressions in C
- 【索引】Rujia Liu's Problems for Beginners
- MediaMetadataRetriever根据指定时间截取帧
- Eclipse+SDK+ADT Android开发环境搭建注意问题
- 欢迎使用CSDN-markdown编辑器
- commons-pool对象池实现原理及使用(二)
- 阻止点击事件冒泡,不让父级元素的点击事件响应
- 【Codeforces418D】Big Problems for Organizers
- LeetCode 68 Text Justification
- 获取电脑日期时间代码段
- Windows 无法启动 VMware Authorization Service 服务
- HDU
- 面试准备之最详细的Handler的使用、源码分析
- JavaScript 原型
- javascript正则表达式
- Unity shader学习之屏幕后期处理效果之Bloom效果