• 会爆栈,dfs传参,只能传1个~~RMQLCA在线


    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #pragma comment(linker, "/STACK:1024000000, 1024000000")
    #include<queue>
    using namespace std;
    
    const int M = 400015;
    struct Edge{
        int v, next;
    } edge[M << 1];
    int cnt;
    int F[M<<1], rmq[M << 1], P[M];
    int dp[20][M<<1];
    int E; int head[M];
    void add_edge(int s, int v){
        edge[E].next = head[s];
        edge[E].v = v;
        head[s] = E ++;
    }
    
    int vis[M];
    int dep[M];
    void dfs(int u){
        cnt ++;
        F[cnt] = u;
        rmq[cnt] = dep[u];
        P[u] = cnt;
        vis[u] = 1;
        for(int i = head[u]; i != -1; i = edge[i].next){
            int v = edge[i].v;
            if(vis[v]) continue;
            dfs(v);
            cnt ++;
            rmq[cnt] = dep[u];
            F[cnt] = u;
        }
    }
    
    void RMQ(int n){
        for(int i = 1; i <= n; i ++) dp[0][i] = i;
        for(int j = 1; (1<<j) <= n; j ++) {
            int tmp = 1<<(j-1);
            for(int i = 1; i + tmp <= n; i ++){
                dp[j][i] = (rmq[dp[j-1][i]] < rmq[dp[j-1][i + tmp]])?dp[j-1][i]:dp[j-1][i + tmp];
            }
        }
    }
    
    int query(int L, int R){
        if(L > R) swap(L, R);
        int t = R - L+1;
        int k = 0;
        while(t >= (1<<(k+1))) k ++;
        return rmq[dp[k][L]] < rmq[dp[k][R-(1<<k) + 1]]?dp[k][L]:dp[k][R-(1<<k) + 1];
    }
    int solve(int a, int b){
        return F[query(P[a], P[b])];
    }
    int dis[M], vv[M];
    void bfs(){
        queue<int> q;
        q.push(1);
        vv[1] = 1;
        dep[1] = 1;
        while(!q.empty()){
            int u = q.front(); q.pop();
            for(int i = head[u]; i != -1; i = edge[i].next){
                int v = edge[i].v;
                if(vv[v]) continue;
                dep[v] = dep[u] + 1;
                vv[v] = 1;
                q.push(v);
            }
        }
    }
    int main(){
        int n, m;
        scanf("%d%d", &n, &m);
        int a, b;
        memset(head, -1, sizeof(head));
        for(int i = 2; i <= n; i ++){
            scanf("%d", &a);
            add_edge(a, i);
            add_edge(i, a);
        }
        cnt = 0;
        bfs();
        dfs(1);
        RMQ(2*n);
        while(m --){
            scanf("%d%d", &a, &b);
            int lc = solve(a, b);
            if(lc == a)
                printf("%d %d
    ", rmq[P[lc]], rmq[P[b]] - rmq[P[lc]]);
            else if(lc == b){
                printf("%d %d
    ", rmq[P[a]] - rmq[P[lc]], rmq[P[lc]]);
            }else {
                printf("%d %d
    ", rmq[P[a]], rmq[P[b]] - rmq[P[lc]]);
            }
        }
        return 0;
    }
    /*
    6 1
    4 1 1 3 3
    5 6
    */
    

      

  • 相关阅读:
    引入包时“”与<>的区别
    Scanners
    一个SQLite数据库的LIKE查询和IN集合查询的代码实例
    @synchronized线程同步互斥锁
    makeKeyAndVisible
    NSString 数字判断
    UILabel UITextField UITextView
    (转载)JAVA SE6.0 中使用SplashScreen
    转帖(http://hi.baidu.com/johnehuang/blog/item/e1e96782a4b04e97f703a6dc.html)
    ce
  • 原文地址:https://www.cnblogs.com/acmood/p/4537852.html
Copyright © 2020-2023  润新知