zoukankan      html  css  js  c++  java
  • 2015北京网络赛 Couple Trees 倍增算法

    2015北京网络赛 Couple Trees

    题意:两棵树,求不同树上两个节点的最近公共祖先

    思路:比赛时看过的队伍不是很多,没有仔细想。今天补题才发现有个 倍增算法,自己竟然不知道。

        解法来自 qscqesze ,这个其实之前如果了解过倍增的话还是不是很难,不过这题的数据也不是很给力,极限数据理论上是过不了的。

        其他解法有树链剖分?并不是很清楚。就这样水过了吧。。。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <fstream>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <deque>
     7 #include <vector>
     8 #include <queue>
     9 #include <string>
    10 #include <cstring>
    11 #include <map>
    12 #include <stack>
    13 #include <set>
    14 #define LL long long
    15 #define eps 1e-8
    16 #define INF 0x3f3f3f3f
    17 #define MAXN 100005
    18 using namespace std;
    19 
    20 int f1[MAXN][20], f2[MAXN][20];
    21 int deep1[MAXN], deep2[MAXN];
    22 int step1, step2, ans;
    23 void work(int x, int y){
    24     step1 = step2 = 1;
    25     while (x != y){
    26         if (x < y){
    27             //x < y means y is not x's ancestor, so let y up
    28             for (int i = 15; i >= 0; i--){
    29                 if (f2[y][i] > x){
    30                     y = f2[y][i];
    31                     step2 += 1 << i;
    32                     break;
    33                 }
    34             }
    35             y = f2[y][0];
    36             step2++;
    37         }
    38         else{
    39             for (int i = 15; i >= 0; i--){
    40                 if (f1[x][i] > y){
    41                     x = f1[x][i];
    42                     step1 += 1 << i;
    43                     break;
    44                 }
    45             }
    46             x = f1[x][0];
    47             step1++;
    48         }
    49     }
    50     ans = x;
    51 }
    52 int main()
    53 {
    54 #ifndef ONLINE_JUDGE
    55     freopen("in.txt", "r", stdin);
    56     //freopen("out.txt", "w", stdout);
    57 #endif // OPEN_FILE
    58     int n, m;
    59     while (~scanf("%d%d", &n, &m)){
    60         int x, y;
    61         deep1[1] = deep2[1] = 1;
    62         for (int i = 0; i <= 15; i++){
    63             f1[1][i] = f2[1][i] = 1;
    64         }
    65         for (int i = 2; i <= n; i++){
    66             scanf("%d", &x);
    67             f1[i][0] = x;
    68             deep1[i] = deep1[x] + 1;
    69             for (int j = 1; j <= 15; j++){
    70                 f1[i][j] = f1[f1[i][j - 1]][j - 1];
    71             }
    72         }
    73         for (int i = 2; i <= n; i++){
    74             scanf("%d", &x);
    75             f2[i][0] = x;
    76             deep2[i] = deep2[x] + 1;
    77             for (int j = 1; j <= 15; j++){
    78                 f2[i][j] = f2[f2[i][j - 1]][j - 1];
    79             }
    80         }
    81         ans = 0;
    82         for (int i = 1; i <= m; i++){
    83             scanf("%d%d", &x, &y);
    84             x = (x + ans) % n + 1;
    85             y = (y + ans) % n + 1;
    86             work(x, y);
    87             printf("%d %d %d
    ", ans, step1, step2);
    88         }
    89     }
    90 }    
  • 相关阅读:
    composer设置国内镜像
    mac安装composer
    composer安装laravel
    How to use MySQL 5.6 with MAMP 3 and MAMP PRO 3
    视觉惯性里程计:IMU预积分
    通过安卓NDK调用opencv4android 并通过adb shell 测试生成的二进制文件
    ubuntu: aptget update的时候遇到“Hash Sum mismatch”错误
    卡尔曼滤波 (Kalman Filter)的一个简单实现: 恒定加速度模型
    双目相机与IMU camera IMU 联合标定工具箱使用方法——Kalibr
    HKUST VINSMONO :香港科大开源VINSSLAM算法 part 2
  • 原文地址:https://www.cnblogs.com/macinchang/p/4831036.html
Copyright © 2011-2022 走看看