Codeforces418D Big Problems for Organizers
来源:互联网 发布:减肥从130到90 知乎 编辑:程序博客网 时间:2024/06/03 00:24
题目链接
题目大意
给定一棵
解题思路
并没有什么思路…甚至还想过块状树…
可以用树的直径来做.
首先把直径从树中抽出来重新编号,把其他的点都变为挂在直径上的某个点上,只需维护每个节点属于的直径上的节点编号以及这两点间的距离,还有直径上节点到挂在它上面的点的最大距离.
然后询问时各种分类讨论,列出表达式变量分离RMQ什么的….
细节巨多,这里空太小,写不下.
于是用ST表可以达到一个奇妙的复杂度:
bblss123还有倍增的做法.
丑丑的代码君
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=1e5+5,LG=18,INF=1e9;int n,tot_edge,tot,mx_dis,ID,head[N],pre[N],id[N],dep[N],mx_dep[N],lg[N],arr[N], ST[2][N][LG];struct Edge{ int to,nxt;}edge[N<<1];inline void add_edge(int from,int to){ edge[tot_edge]=(Edge){to,head[from]}; head[from]=tot_edge++;}void rd(int &res){ res=0; char c; while(c=getchar(),c<48); do res=(res<<3)+(res<<1)+(c^48); while(c=getchar(),c>47);}inline void Max(int &a,int b){ if(b>a)a=b;}void dfs(int cur,int par,int depth){ if(depth>=mx_dis){ mx_dis=depth; ID=cur; } pre[cur]=par; for(int i=head[cur];~i;i=edge[i].nxt){ int to=edge[i].to; if(to==par)continue; dfs(to,cur,depth+1); }}void assign_dfs(int cur,int belong,int depth){ id[cur]=belong; Max(mx_dep[belong],dep[cur]=depth); for(int i=head[cur];~i;i=edge[i].nxt){ int to=edge[i].to; if(~id[to])continue; assign_dfs(to,belong,depth+1); }}void assign(){ memset(id,-1,n+1<<2); for(int cur=ID,cnt=0;~cur;cur=pre[cur]){ id[cur]=cnt; arr[cnt++]=cur; } tot=mx_dis+1; for(int i=0;i<tot;++i) assign_dfs(arr[i],i,0);}void init(){ mx_dis=ID=-1; dfs(1,-1,0); dfs(ID,-1,0); assign(); for(int i=0;i<tot;++i){ ST[0][i][0]=mx_dep[i]-i; ST[1][i][0]=mx_dep[i]+i; } for(int j=1;1<<j<=tot;++j) for(int i=0;i+(1<<j)<=tot;++i) for(int k=0;k<2;++k) ST[k][i][j]=max(ST[k][i][j-1],ST[k][i+(1<<j-1)][j-1]); for(int i=2,j=1;i<=tot+1;++i){ lg[i]=j; if(!(i&(i-1)))++j; }}int query_mx(bool type,int L,int R){ if(L>R)return -INF; int k=lg[R-L+2]-1; return max(ST[type][L][k],ST[type][R-(1<<k)+1][k]);}int solve(int u,int v){ if(id[u]==id[v]){ if(dep[u]>dep[v])swap(u,v); return max(id[u],tot-1-id[u])+dep[u]; } if(id[u]>id[v])swap(u,v); int mid=id[u]-dep[u]+id[v]+dep[v]>>1,ans=0; if(mid<id[u]){ Max(ans,query_mx(0,0,id[v]-1)+id[v]+dep[v]); Max(ans,dep[v]); Max(ans,query_mx(1,id[v]+1,tot-1)-id[v]+dep[v]); } else if(mid>=id[v]){ Max(ans,query_mx(0,0,id[u]-1)+id[u]+dep[u]); Max(ans,dep[u]); Max(ans,query_mx(1,id[u]+1,tot-1)-id[u]+dep[u]); } else{ Max(ans,query_mx(0,0,id[u]-1)+id[u]+dep[u]); Max(ans,dep[u]); Max(ans,query_mx(1,id[u]+1,mid)-id[u]+dep[u]); Max(ans,query_mx(0,mid+1,id[v]-1)+id[v]+dep[v]); Max(ans,dep[v]); Max(ans,query_mx(1,id[v]+1,tot-1)-id[v]+dep[v]); } return ans;}int main(){ int sz=128<<20; char *p=(char*)malloc(sz)+sz; __asm__("movl %0, %%esp\n" :: "r"(p)); int m,u,v; rd(n); tot_edge=0; memset(head,-1,n+1<<2); for(int i=1;i<n;++i){ rd(u);rd(v); add_edge(u,v); add_edge(v,u); } init(); rd(m); while(m--){ rd(u);rd(v); printf("%d\n",solve(u,v)); } return 0;}/* Jun.01.16 Tags:Tree Submissions:4 Time 93ms Memory 151600KB*/
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
- mysql的插入数据和查询
- 聚类算法实践(二)——谱聚类、Chameleon聚类
- [HNOI2011]XOR和路径
- iOS——UICollectionView
- 不使用第三个变量来交换连个数据
- Codeforces418D Big Problems for Organizers
- Android版日语学习应用的逆向分析
- C++中头文件的使用
- 一个Linux下的网络模拟工具 Core
- 进程—僵尸进程与孤儿进程
- 基于R语言的模型组合
- Centos 6,7 YUM本地源,网络源
- spring ioc原理
- Django Model实例