2017-11-3离线赛总结
2017-11-03 18:00
274 查看
有一段时间没有离线赛了,感觉这次考得还过得去
失分小结:
估分:240
实际分数:230
万万没想到自己第二题的n^3可以卡过去,正解为LCP(最长公共前缀)
第三题就是抽直径,然后就分类讨论
注意直径的性质:距离一点最远的点一定是直径两端点中的一点
设两个机房分别在a,b,他们在直径上对应的点为u,v
那么答案就会在Lt到u或u到v或v到Rt的路径上,然后由于满足单调性
对于中间的那部分,可以直接利用公式推算
失分小结:
估分:240
实际分数:230
万万没想到自己第二题的n^3可以卡过去,正解为LCP(最长公共前缀)
第三题就是抽直径,然后就分类讨论
注意直径的性质:距离一点最远的点一定是直径两端点中的一点
设两个机房分别在a,b,他们在直径上对应的点为u,v
那么答案就会在Lt到u或u到v或v到Rt的路径上,然后由于满足单调性
对于中间的那部分,可以直接利用公式推算
#include<cstdio> #include<iostream> using namespace std; #define M 100005 inline void chk_mx(int &x,int y){if(x<y)x=y;} int To[M<<1],nxt[M<<1],head[M],tta; void addedge(int a,int b){nxt[++tta]=head[a];head[a]=tta;To[tta]=b;} #define LFOR(i,x) for(int i=head[x];~i;i=nxt[i]) int n,dep[M],fa[M],mark[M],dis[M],Fr[M],Mx[M],Num[M],Real[M]; void dfs(int x,int f,int &t){ dep[x]=dep[f]+1; fa[x]=f; if(dep[t]<dep[x])t=x; LFOR(i,x){ int y=To[i]; if(y==f)continue; dfs(y,x,t); } } void mdfs(int x,int f,int a){ Fr[x]=a; dis[x]=dis[f]+1; if(Mx[a]<dis[x])Mx[a]=dis[x]; LFOR(i,x){ int y=To[i]; if(mark[y]||y==f)continue; mdfs(y,x,a); } } int Lt,Rt; struct Segment_Tree{ struct node{int l,r,mx;}tree[M<<2]; void build(int l,int r,int p,int flag){ tree[p].l=l,tree[p].r=r; if(l==r){ if(flag)tree[p].mx=Mx[Real[l]]-dep[Real[l]]; else tree[p].mx=Mx[Real[l]]+dep[Real[l]]; return; } int mid=(l+r)>>1; build(l,mid,p<<1,flag);build(mid+1,r,p<<1|1,flag); tree[p].mx=max(tree[p<<1].mx,tree[p<<1|1].mx); } int query(int l,int r,int p){ if(tree[p].l==l&&tree[p].r==r)return tree[p].mx; int mid=(tree[p].l+tree[p].r)>>1; if(mid>=r)return query(l,r,p<<1); else if(mid<l)return query(l,r,p<<1|1); else return max(query(l,mid,p<<1),query(mid+1,r,p<<1|1)); } }Lee,Ree; void init(){ dep[0]=-1,dis[0]=-1; dfs(1,0,Lt); dfs(Lt,0,Rt);//Lt-->Rt int t=dep[Rt]+1; int p=Rt;while(p){Real[t]=p;Num[p]=t--;mark[p]=1;p=fa[p];}//抽直径 p=Rt;while(p){mdfs(p,0,p);p=fa[p];} //find max Lee.build(1,Num[Rt],1,0); Ree.build(1,Num[Rt],1,1); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)head[i]=-1; for(int i=1;i<n;i++){ int x,y; scanf("%d%d",&x,&y); addedge(x,y);addedge(y,x); } init(); int m; scanf("%d",&m); while(m--){ int x,y; scanf("%d%d",&x,&y); int u=Fr[x],v=Fr[y]; if(dep[u]>dep[v])swap(u,v),swap(x,y); int ans=0; chk_mx(ans,min(dis[y]+dep[v],dis[x]+dep[u])); chk_mx(ans,min(dep[Rt]-dep[u]+dis[x],dep[Rt]-dep[v]+dis[y])); int pos=(dis[y]-dis[x]+dep[u]+dep[v])>>1;pos++; if(pos>Num[u])chk_mx(ans,Lee.query(Num[u]+1,pos,1)-dep[u]+dis[x]); if(pos+1<Num[v])chk_mx(ans,dis[y]+dep[v]+Ree.query(pos+1,Num[v]-1,1)); printf("%d\n",ans); } return 0; }
相关文章推荐
- 2017-11-3离线赛总结
- 2017-10-21离线赛总结
- 2017-9-29离线赛总结
- Xmpp问题总结:XMPP离线管理
- 2017-10-26离线赛总结
- 20171009离线赛总结
- 2017-10-9离线赛总结
- 2017-11-5离线赛总结(NOIP七连测第三场)
- 2017.10.19离线赛总结
- 离线缓存与客户端存储总结
- 星星之火,可以燎原!------------完整的ubuntu镜像源/本地源/更新源/离线升级包!制作总结
- 2017-10-23离线赛总结
- LCA 最近公共祖先 tarjan离线 总结 结合3个例题
- 2017-9-28离线赛总结
- 2017.10.11离线赛总结
- [zz]完整的ubuntu镜像源/本地源/更新源/离线升级包!制作总结!
- LCA 最近公共祖先 tarjan离线 总结 结合3个例题
- 离线赛20171007总结
- 2017-10-8离线赛总结
- 2017-11-4离线赛总结(NOIP七连测第二场)