Codeforces418D Big Problems for Organizers

原创 2016年06月01日 20:44:08

题目链接

题目大意

给定一棵n个节点的树,m次询问,每次给出两个点u,v,求

max{min(dist(i,u),dist(i,v))}.

n,m105.

解题思路

并没有什么思路…甚至还想过块状树…
可以用树的直径来做.
首先把直径从树中抽出来重新编号,把其他的点都变为挂在直径上的某个点上,只需维护每个节点属于的直径上的节点编号以及这两点间的距离,还有直径上节点到挂在它上面的点的最大距离.
然后询问时各种分类讨论,列出表达式变量分离RMQ什么的….
细节巨多,这里空太小,写不下.
于是用ST表可以达到一个奇妙的复杂度:
O(nlgn)预处理,O(1)查询.
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

*/
版权声明:原创文章,转载请注明出处哟~~

ubuntu 64位下安装wps

首先,去官网下载wps。地址:http://community.wps.cn/download/ 然后切换到下载目录,执行如下命令: $ sudo apt-get install ia32-lib...
  • iAm333
  • iAm333
  • 2014年08月04日 17:35
  • 2196

算法学习之“Big Oh Notation”

一、Asymptotic analysis Suppose we are considering two algorithms, A and B, for solving a given pro...
  • Sagittarius_Warrior
  • Sagittarius_Warrior
  • 2015年12月08日 10:36
  • 809

js全屏显示显示代码的三种方法

第一种:        在已经打开的一个普通网页上,点击“全屏显示”,然后进入该网页对应的全屏模式。方法为:在网页的与之间加入以下代码:  代码如下:            ...
  • u011672712
  • u011672712
  • 2013年11月12日 09:28
  • 598

Big Bang 详细介绍,锤子科技至今最好的技术

当你第一次看到这个输入法的时候,一定会为这个想法感到 很特别。------来自于锤子科技...
  • qq_15427331
  • qq_15427331
  • 2017年01月18日 16:33
  • 1585

PAT(乙级)1002 数字分类 (20)

问题来源:http://www.nowcoder.com/pat/6/problems 题目描述 给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字: A1 = 能被5整除...
  • u014594922
  • u014594922
  • 2016年09月03日 20:00
  • 123

大端序(big-edian)和 小端序(little-endian)

在各种计算机体系结构中,对于字节、字等的存储机制有所不同,因而引发了计算机通信领域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。如果不达成一致的规...
  • xiezhongtian
  • xiezhongtian
  • 2014年02月22日 13:54
  • 1750

Eclipse导入Github上的Robotium源码进行代码分析的步骤

这篇文章应该只是针对像我这样的初级Maven用户的,因为自己花了不少时间来解决这个问题,而网上很多文章描述的也是语焉不详,所以记录下来以便后来如我者可以借鉴一二。文中有几点细节我觉得需要注意的我会高亮...
  • zhubaitian
  • zhubaitian
  • 2014年09月25日 12:46
  • 3580

详解Big-Endian和Little-Endian,大端模式和小端模式

详解大端模式和小端模式 嵌入式开发交流群280352802,欢迎加入! 一、大端模式和小端模式的起源         关于大端小端名词的由来,有一个有趣的故事,来自于Jonathan Swift的...
  • zhangpinghao
  • zhangpinghao
  • 2013年11月01日 22:00
  • 2070

ARM——big.LITTLE 架构处理器基础

big.LITTLE 处理 ARM big.LITTLE™ 处理是一项节能技术,它将最高性能的 ARM CPU 与最高效的 ARM CPU 结合到一个处理器子系统中,与当今业内最优秀的系统相比,不...
  • hannax
  • hannax
  • 2013年10月07日 18:54
  • 1750

《大数据时代(BIG DATA)》

—-豆瓣链接—- 大数据的时代思维变革 不是随机样本,而是全体数据 小数据时代的随机采样,最少的数据获得最多的信息 采样分析的精确性随着采样随机性的增加而大幅提高,但与样本数量的增加...
  • my_precious
  • my_precious
  • 2016年10月12日 09:56
  • 1164
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Codeforces418D Big Problems for Organizers
举报原因:
原因补充:

(最多只允许输入30个字)