• BC ROUND 43# 03 HDU 5266


    弱啊弱啊,我用了扩展指令,然后大牛告诉我,只对VC++有用,对G++没用的。。shit,三题就这样没了。

    方法是使用ST在线算法,O(1)查询,然后用线段树维护。。呃感觉这个好慢。看了大斌神的是用LCA倍增+维护一个表 ,得学习一下。。。

    先贴弱的代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #pragma comment(linker, "/STACK:102400000,102400000")
    using namespace std;
    
    const int N=300015;
    
    struct Edge{
        int u,v,next;
    }edge[N*2];
    int head[N],tot,dtot;
    int dp[N*2][20];
    int ver[2*N],R[2*N],first[N],dir[N];
    bool vis[N];
    int ans;
    int tag[N*4];
    
    void addedge(int u,int v){
        edge[tot].u=u;
        edge[tot].v=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    
    void dfs(int u ,int dep) {  
        vis[u] = true; ver[++dtot] = u; first[u] = dtot; R[dtot] = dep;  
        for(int k=head[u]; k!=-1; k=edge[k].next)  
            if( !vis[edge[k].v] ) {  
                int v = edge[k].v ;
                dfs(v,dep+1);  
                ver[++dtot] = u; R[dtot] = dep;  
            }  
    }
    
    void ST(int n) {  
        for(int i=1;i<=n;i++)  
            dp[i][0] = i;  
        for(int j=1;(1<<j)<=n;j++) {  
            for(int i=1;i+(1<<j)-1<=n;i++) {  
                int a = dp[i][j-1] , b = dp[i+(1<<(j-1))][j-1];  
                dp[i][j] = R[a]<R[b]?a:b;  
            }  
        }  
    }
    
    int RMQ(int l,int r)  {  
        int k=0;  
        while((1<<(k+1))<=r-l+1)  
            k++;  
        int a = dp[l][k], b = dp[r-(1<<k)+1][k]; 
        return R[a]<R[b]?a:b;  
    }
    
    int LCA(int u ,int v)  {  
        int x = first[u] , y = first[v];  
        if(x > y) swap(x,y);  
        int res = RMQ(x,y);  
        return ver[res];  
    }
    
    void query(int rt,int l,int r,int L,int R){
    //    cout<<L<<" "<<R<<endl;
        if(tag[rt]!=-1&&l<=L&&R<=r){
            if(ans==-1) ans=tag[rt];
            else {
                ans=LCA(ans,tag[rt]);
            }
            return ;
        }
        else if(L==R){
        //    cout<<L<<" "<<ans<<endl;
            tag[rt]=L;
            if(ans==-1)
                ans=L;
            else{
                ans=LCA(ans,L);
            }
            return ;
        }
        int m=(L+R)>>1;
        if(r<=m){
            query(rt<<1,l,r,L,m);
        }
        else if(l>=m+1){
            query(rt<<1|1,l,r,m+1,R);
        }
        else{
            query(rt<<1,l,r,L,m);
            query(rt<<1|1,l,r,m+1,R);
        }
        if(tag[rt<<1]!=-1&&tag[rt<<1|1]!=-1)
        tag[rt]=LCA(tag[rt<<1],tag[rt<<1|1]);
    }
    
    int main(){
        int n,q,u,v;
        while(scanf("%d",&n)!=EOF){
            memset(head,-1,sizeof(int)*(n+5));
            memset(vis,false,sizeof(bool)*(n+5));
            memset(tag,-1,sizeof(int)*(n*4));
            tot=0;
            for(int i=1;i<n;i++){
                scanf("%d%d",&u,&v);
                addedge(u,v);
                addedge(v,u);
            }
            dtot=0;
            dfs(1,1);
            ST(2*n-1);
            tag[1]=1;
            scanf("%d",&q);
        //    printf("%d",LCA(2,3));
        //    printf("%d",LCA(1,2));
        //    printf("%d",LCA(3,4));
            while(q--){
                scanf("%d%d",&u,&v);
                ans=-1;
                query(1,u,v,1,n);
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    What does the LayoutAwarePage Class provide
    UML类图几种关系的总结
    WriteableBitmap 巧学巧用
    iOS图片填充UIImageView(contentMode)
    UIImage扩展用代码直接改变图片大小
    iOS各框架功能简述以及系统层次结构简单分析
    【深拷贝VS浅拷贝】
    【node】node连接mongodb操作数据库
    【node】mongoose的基本使用
    【node】websocket
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4559297.html
Copyright © 2020-2023  润新知