zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Android之vector代码修改颜色
    一个关于native sql的程序
    webdynpro 下拉列表控件
    webdynpro tree控件使用
    webdynpro MESSGAE
    webdynpro的select_option示例
    一个简单的webdynpro的ALV示例
    ALV前导零的问题
    自动流水号
    OO的ALV隐藏工具栏的form
  • 原文地址:https://www.cnblogs.com/wa007/p/9963941.html
Copyright © 2011-2022 走看看