2021 Training League Warm-up Training Game Second J.owest Common Ancestor

Topic link

The main idea of ​​the topic: a hexadecimal complete binary tree, let you find the nearest common ancestor (LCA) of two numbers.


Idea: First of all, let you understand the nature of binary: it is
Insert picture description here
a bit ugly, just look at it, because the root starts from 1, so if there is a point that is x, then its left child is 2 ∗ x 2*x2x , and his child is2 ∗ x + 1 2*x+12x+1. Then combined with the binary is to shift one bit to the left, if the left subtree is the next bit 0, otherwise it is 1, so we can know that the subtree of a point must be shifted to the left by him. It is two numbers The prefix of (binary) is their nearest common ancestor (LCA), and the relationship between binary and hexadecimal is that a hexadecimal can be converted into a 4-digit binary number, then we can first convert the hexadecimal to 2 Then convert the binary system to hexadecimal system. Be careful not to prefix 0. Finally, you must add it first to prevent the last 4 digits from being lost. Finally, eliminate the prefix 0.

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 +7 ;
const ll mod = 1e9 + 7;

#define mst(x, a) memset( x,a,sizeof(x) )
#define rep(i, a, b) for(int i=(a);i<=(b);++i)
#define dep(i, a, b) for(int i=(a);i>=(b);--i)

inline ll read() {
    
    
    ll x = 0;
    bool f = 0;
    char ch = getchar();
    while (ch < '0' || '9' < ch)
        f |= ch == '-', ch = getchar();
    while ('0' <= ch && ch <= '9')
        x = x * 10 + ch - '0', ch = getchar();
    return f ? -x : x;
}

void out(ll x) {
    
    
    int stackk[20];
    if (x < 0) {
    
    
        putchar('-');
        x = -x;
    }
    if (!x) {
    
    
        putchar('0');
        return;
    }
    int top = 0;
    while (x)
        stackk[++top] = x % 10, x /= 10;
    while (top)
        putchar(stackk[top--] + '0');
}
ll qpow(ll a,ll b) {
    
    
    ll ans=1;
    while(b) {
    
    
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}


string str,s;
map<char,string >mp;
map<string,char >mpp;
int main() {
    
    
    int _=read();
    mp['0']="0000";
    mp['1']="0001";
    mp['2']="0010";
    mp['3']="0011";
    mp['4']="0100";
    mp['5']="0101";
    mp['6']="0110";
    mp['7']="0111";
    mp['8']="1000";
    mp['9']="1001";
    mp['a']="1010";
    mp['b']="1011";
    mp['c']="1100";
    mp['d']="1101";
    mp['e']="1110";
    mp['f']="1111";

    mpp["0000"]='0';
    mpp["0001"]='1';
    mpp["0010"]='2';
    mpp["0011"]='3';
    mpp["0100"]='4';
    mpp["0101"]='5';
    mpp["0110"]='6';
    mpp["0111"]='7';
    mpp["1000"]='8';
    mpp["1001"]='9';
    mpp["1010"]='a';
    mpp["1011"]='b';
    mpp["1100"]='c';
    mpp["1101"]='d';
    mpp["1110"]='e';
    mpp["1111"]='f';
    ll T=0;
    while(_--) {
    
    
        cin>>str>>s;
        string ans_str,ans_s;
        string ans,ans1;
        for(int i=0; i<str.size(); i++) {
    
    
            ans_str+=mp[str[i]];
        }
        for(int i=0; i<s.size(); i++) {
    
    
            ans_s+=mp[s[i]];
        }
        for(int i=0; i<ans_str.size(); i++) {
    
    
            if(ans_str[i]=='0') {
    
    
                continue;
            } else {
    
    
                ans_str=ans_str.substr(i,ans_str.size()-i);
                break;
            }
        }
        for(int i=0; i<ans_s.size(); i++) {
    
    
            if(ans_s[i]=='0') {
    
    
                continue;
            } else {
    
    
                ans_s=ans_s.substr(i,ans_s.size()-i);
                break;
            }
        }

        ///cout<<ans_str<<endl;
        ///cout<<ans_s<<endl;
        for(int i=0; i<min(ans_str.size(),ans_s.size()); i++) {
    
    
            if(ans_str[i]==ans_s[i]) {
    
    
                ans=ans+ans_str[i];
            } else break;
        }

        ans="00000"+ans;///这个地方出过一次锅
        for(int i=ans.size()-1; i>=3; i-=4) {
    
    
            string q=ans.substr(i-3,4);
            ans1=mpp[q]+ans1;
        }

        for(int i=0; i<ans1.size(); i++) {
    
    
            if(ans1[i]=='0') {
    
    
                continue;
            } else {
    
    
                ans1=ans1.substr(i,ans1.size()-i);
                break;
            }
        }
        printf("Case #%lld: ",++T);
        cout<<ans1<<endl<<endl;

    }
    return 0;

}


Guess you like

Origin blog.csdn.net/weixin_45911397/article/details/114799054