zoukankan      html  css  js  c++  java
  • 2016vijos 6-1 松鼠聚会(LCA+卡空间)

    求LCA,N=1e6,原空间限制8MB

    求LCA需要深度,需要跳跃一定距离的祖先,需要父节点

    把一个整数压成3个char,f[]存父节点

    g[],深度为奇数的点存往上跳576步能到的点,深度为偶数的点存深度

    如果深度为奇数的点要求它的深度,求他父节点的深度+1

    如果深度为偶数的点要求它往上跳576步的祖先,先往上跳一步,变成奇数深度

    如何求往上跳576步的祖先?

    1、往上跳6次1步,g就存的往上跳6步的祖先

    2、往上跳6次6步,g就存的往上跳36步的祖先

    3、往上跳4次36步,g就存的往上跳144步的祖先

    4、往上跳4次144步,g就存的往上跳576步的祖先

    还有,不能开iostream库,不然爆空间。。。

    #include<cstdio>
    
    using namespace std;
    
    #define N 1000001
    
    const int D=576;
    
    struct node
    {
        char a,b,c;
    }f[N],g[N];
    
    inline int F(int i)
    {
        return ((f[i].a<<7)+f[i].b<<7)+f[i].c; 
    }
    
    inline int G(int i)
    {
        return ((g[i].a<<7)+g[i].b<<7)+g[i].c; 
    }
    
    inline int d(int i)
    {
        return G(i)<N ? G(i):G(F(i))+1;
    }
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); }
    }    
    
    node turn(int x)
    {
        node y;
        y.a=x>>14;
        y.b=(x>>7)&127;
        y.c=x&127;
        return y;
    }
    
    int lca(int x,int y)
    {
        int u;
        if(d(x)<d(y)) u=x,x=y,y=u;
        int dis=d(x)-d(y);
        while(dis>=D)
        {
            if(G(x)<N) x=F(x),dis--;
            else x=G(x)-N,dis-=D;
        }
        while(dis) x=F(x),dis--;
        while(x!=y)
        {
            if(G(x)<N||G(x)==G(y)) x=F(x),y=F(y);
            else x=G(x)-N,y=G(y)-N;
        }
        return x; 
    }
    
    int main()
    {
        freopen("squirrel.in","r",stdin);
        freopen("squirrel.out","w",stdout);
        int n,m;
        read(n); read(m);
        g[0]=turn(N);
        int x;
        for(int i=2;i<=n;++i) 
        {
            read(x);
            f[i]=turn(x),g[i]=turn(G(F(i))+1);
        }
        for(int i=n;i;i--)
            if(G(i)&1)
            {
                x=i;
                for(int j=1;j<=6;++j) x=F(x);
                g[i]=turn(x+N);
            }
        for(int i=n;i;i--)
            if(G(i)>N)
            {
                x=i;
                for(int j=1;j<=6;++j) x=G(x)-N;
                g[i]=turn(x+N);
            }
        for(int i=n;i;i--)
            if(G(i)>N)
            {
                x=i;
                for(int j=1;j<=4;++j) x=G(x)-N;
                g[i]=turn(x+N);
            }
        for(int i=n;i;i--)
            if(G(i)>N)
            {
                x=i;
                for(int j=1;j<=4;++j) x=G(x)-N;
                g[i]=turn(x+N);
            }
        int y;
        while(m--)
        {
            read(x); read(y);
            printf("%d
    ",lca(x,y));
        }
    }
  • 相关阅读:
    「Codeforces 724F」Uniformly Branched Trees
    「笔记」组合入门题选做
    「算法笔记」组合入门与应用
    「算法笔记」可持久化线段树
    「算法笔记」期望 DP 入门
    「NOIP 2016」换教室
    「算法笔记」基础数论
    「笔记」关于乱搞
    python 的列表遍历删除
    Python基础第三篇:函数
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8971405.html
Copyright © 2011-2022 走看看