• Codeforces 1062 E. Company


    在自闭的边缘疯狂试探。。。。

    题目直通车:http://codeforces.com/contest/1062/problem/E

    lca+线段树

    首先要明白题意,即删除[l,r]中的任意一个元素,使得其他点的最近公共祖先的深度最大

    在树的点区间上建立线段树,维护区间的 所有点的最近公共祖先,不包含最左点的公共祖先,不包含最右点的公共祖先,不包含任意一点的其他点的深度最大的公共祖先和相应的不包含的点的id(序号),在线段树上依次维护,不包含任意一点的其他点的深度最大的公共祖先可以由该区间的左右区间分别得到,具体细节参见代码

    #include<iostream>
    #include<cstdio> 
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<string.h>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #include<stack>
    #include<map>
    #include<fstream>
    #include<cstdlib>
    #include<ctime>
    #include<list>
    #include<climits>
    #include<bitset>
    #include<random>
    using namespace std;
    #define fopen freopen("input.in", "r", stdin);freopen("output.in", "w", stdout);
    #define left asfdasdasdfasdfsdfasfsdfasfdas1
    #define right asfdasdasdfasdfsdfasfsdfasfdas2
    #define y1 asfdasdasdfasdfsdfasfsdfasfdas3
    typedef long long ll;
    typedef unsigned ui;
    typedef long double ld;
    const int dell[8][2]={{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}};
    ll mod=1e9+7;
    const ll inf=(1LL<<31)-1;
    const int maxn=1e5+7;
    const int maxm=1e6+7;
    const double eps=1e-8;
    const double pi=acos(-1.0);
    const int csize=22;
    int n,k,m,ar[maxn];
    struct node{
        int b,nex;
    }no[maxn];
    int head[maxn],sz;
    int ft[maxn<<1],st[maxn<<1],dfs_clock,pos[maxn],ta[maxn<<1][20],dep[maxn];
    void init(){
        memset(head,-1,sizeof(head));
        sz=0;
        dfs_clock=0;
    }
    void add(int a,int b){
        no[sz].b=b;
        no[sz].nex=head[a];
        head[a]=sz++;
    }
    void dfs(int u,int fa){
        dep[u]=dep[fa]+1;
        st[dfs_clock]=u;
        pos[u]=dfs_clock++;
        for(int i=head[u];i!=-1;i=no[i].nex){
            int v=no[i].b;
            if(v==fa)continue;
            dfs(v,u);
            st[dfs_clock++]=u;
        }
    }
    void init_rmq(){
        memset(ta,0,sizeof(ta));
        for(int i=0;i<dfs_clock;i++)ta[i][0]=st[i];
        for(int j=1;j<20;j++){
            for(int i=0;i<dfs_clock;i++){
                if(i+(1<<j)-1>=dfs_clock)break;
                if(dep[ta[i][j-1]]<dep[ta[i+(1<<j-1)][j-1]])ta[i][j]=ta[i][j-1];
                else ta[i][j]=ta[i+(1<<j-1)][j-1];
            }
        }
    }
    int samefather(int a,int b){
        a=pos[a];
        b=pos[b];
        if(a>b)swap(a,b);
        int ins=0;
        while((1<<1+ins)<=b-a+1)ins++;
        if(dep[ta[a][ins]]<dep[ta[b-(1<<ins)+1][ins]])return ta[a][ins];
        else return ta[b-(1<<ins)+1][ins];
    }
    int mn1[maxn<<3],mn2[maxn<<3],pp[maxn<<3];
    int mn[maxn<<3],mn3[maxn<<3];
    int x,y;
    void build(int l,int r,int o){
        if(l==r-1){
            mn[o]=samefather(l,r);
            if(dep[l]<dep[r]){
                mn3[o]=r;
                pp[o]=l;
            }
            else{
                mn3[o]=l;
                pp[o]=r;
            }
            mn1[o]=r;
            mn2[o]=l;
            return ;
        }
        int mid=l+r>>1;
        build(l,mid,o<<1);
        build(mid,r,o<<1|1);
        mn1[o]=samefather(mn1[o<<1],mn[o<<1|1]);
        mn2[o]=samefather(mn[o<<1],mn2[o<<1|1]);
        mn[o]=samefather(mn[o<<1],mn[o<<1|1]);
        mn3[o]=0;
        if(dep[mn3[o]]<dep[mn1[o]]){
            mn3[o]=mn1[o];
            pp[o]=l;
        }
        if(dep[mn3[o]]<dep[mn2[o]]){
            mn3[o]=mn2[o];
            pp[o]=r;
        }
        int val=samefather(mn2[o<<1],mn1[o<<1|1]);
        if(dep[mn3[o]]<dep[val]){
            mn3[o]=val;
            pp[o]=mid;
        }
        val=samefather(mn3[o<<1],mn[o<<1|1]);
        if(dep[mn3[o]]<dep[val]){
            mn3[o]=val;
            pp[o]=pp[o<<1];
        }
        val=samefather(mn[o<<1],mn3[o<<1|1]);
        if(dep[mn3[o]]<dep[val]){
            mn3[o]=val;
            pp[o]=pp[o<<1|1];
        }
        //cout<<l<<" "<<r<<" "<<mn[o]<<" "<<mn3[o]<<endl;
    }
    void que(int l,int r,int o,int &mm,int &m1,int& m2,int& m3,int& p){
        //cout<<l<<" "<<r<<endl;
        if(l>=x && r<=y){
            mm=mn[o];m1=mn1[o];m2=mn2[o];m3=mn3[o];p=pp[o];
            return ;
        }
        int mid=l+r>>1;
        if(y<=mid){
            que(l,mid,o<<1,mm,m1,m2,m3,p);
        }
        else if(x>=mid){
            que(mid,r,o<<1|1,mm,m1,m2,m3,p);
        }
        else{
            int mm1,mm2,m11,m12,m21,m22,m31,m32,p1,p2;
            que(l,mid,o<<1,mm1,m11,m21,m31,p1);
            que(mid,r,o<<1|1,mm2,m12,m22,m32,p2);
            m1=samefather(m11,mm2);
            m2=samefather(mm1,m22);
            mm=samefather(mm1,mm2);
            m3=0;
            if(dep[m3]<dep[m1]){
                m3=m1;
                p=x;
            }
            if(dep[m3]<dep[m2]){
                m3=m2;
                p=y;
            }
            int val=samefather(m21,m12);
            if(dep[m3]<dep[val]){
                m3=val;
                p=mid;
            }
            val=samefather(m31,mm2);
            if(dep[m3]<dep[val]){
                m3=val;
                p=p1;
            }
            val=samefather(mm1,m32);
            if(dep[m3]<dep[val]){
                m3=val;
                p=p2;
            }
        }
    }
    int main()
    {
        //fopen
        //freopen("input.in","r",stdin);
        scanf("%d%d",&n,&m);
        init();
        for(int i=2;i<=n;i++){
            int x;scanf("%d",&x);
            add(x,i);
        }
        dep[0]=-1;
        dfs(1,0);
        init_rmq();
        build(1,n,1);
        while(m--){
            scanf("%d%d",&x,&y);
            //cout<<"x,y = "<<x<<" "<<y<<endl;
            int mm,m1,m2,m3,p;
            que(1,n,1,mm,m1,m2,m3,p);
            //cout<<"m3 = "<<m3<<endl;
            printf("%d %d
    ",p,dep[m3]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    为什么puppeteer比selenium好?
    Puppeteer
    js跳出多层循环
    webpack loader- 图片处理
    webpack的loader的原理和实现
    Webpack中Loader的pitch方法
    url-loader和file-loader区别
    Vue中强制组件重新渲染的正确方法
    ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION :浏览器下载报错
    JSBridge的原理及使用
  • 原文地址:https://www.cnblogs.com/wa007/p/9963941.html
Copyright © 2020-2023  润新知