zoukankan      html  css  js  c++  java
  • luogu 2152

    SuperGcd

    二进制算法

    1. A = B, Gcd(A, B) = A;

    2. A,B为偶数,  Gcd(A, B) = 2 * Gcd(A / 2, B / 2);

    3. A 为偶数, B 为奇数,Gcd(A, B) = Gcd(A / 2, B);

    4. A,B为奇数, Gcd(A, B) = Gcd(A - B, B)

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <string>
    #include <cmath>
    #include <cstring>
    
    using namespace std;
    const int N = 2e5 + 10;
    
    int C[N * 2];
    char s[N];
    
    struct Node {
        inline void Init(int A[]) {
            scanf("%s", s); int Len = strlen(s); A[0] = Len; for(int i = 1; i <= Len; i ++) A[i] = s[i - 1] - '0';
        }
        inline int Cmp(int A[], int B[]) {
            if(A[0] > B[0]) return 1; if(A[0] < B[0]) return -1;
            for(int i = 1; i <= A[0]; i ++) if(A[i] > B[i]) return 1; else if(A[i] < B[i]) return -1;
            return 0;
        }
        inline void Div(int A[]) {
            int tmp(0), j = 1;
            for(int i = 1; i <= A[0]; i ++) {tmp += A[i]; A[i] = tmp / 2; tmp %= 2; tmp *= 10;}
            for(int i = 1; i <= A[0] && !A[i]; i ++, j = i); A[0] = A[0] - j + 1;
            for(int i = 1; i <= A[0]; i ++) A[i] = A[i + j - 1];
        }
        inline void Minus(int A[], int B[]) {
            for(int i = B[0], j = A[0]; i >= 1; i --, j --) {
                if(A[j] < B[i]) {A[j] += 10; A[j - 1] --;} A[j] -= B[i];
            }
            int j = 1;
            for(int i = 1; i <= A[0] && !A[i]; i ++, j = i); A[0] = A[0] - j + 1;
            for(int i = 1; i <= A[0]; i ++) A[i] = A[i + j - 1];
        }
        int a[N], b[N];
        inline void Mul(int A[], int B[]) {
            memset(C, 0, sizeof C);
            int j = 0; for(int i = A[0]; i >= 1; i --) a[++ j] = A[i];
            j = 0; for(int i = B[0]; i >= 1; i --) b[++ j] = B[i];
            for(int i = 1; i <= A[0]; i ++) {
                int x = 0;
                for(int k = 1; k <= B[0]; k ++) {C[i + k - 1] += a[i] * b[k] + x; x = C[i + k - 1] / 10; C[i + k - 1] %= 10;}
                C[i + B[0]] = x;
            }
            j = A[0] + B[0]; while(!C[j] && j > 1) j --; A[0] = 0;
            for(int i = j; i >= 1; i --) A[++ A[0]] = C[i];
        }
        inline void Out(int A[]) {for(int i = 1; i <= A[0]; i ++) printf("%d", A[i]);}
    } Big_num_work;
    
    void Gcd(int A[], int B[], int &tot) {
        int imp = Big_num_work.Cmp(A, B); if(imp == 0) return ; if(imp < 0) {Gcd(B, A, tot); return ;}
        int ta(0), tb(0); if(A[A[0]] % 2 == 0) Big_num_work.Div(A), ta = 1; if(B[B[0]] % 2 == 0) Big_num_work.Div(B), tb = 1;
        if(ta && tb) Gcd(A, B, ++ tot);
        else if(!ta && !tb) {Big_num_work.Minus(A, B); Gcd(A, B, tot);}
        else Gcd(A, B, tot);
    }
    
    int A[N], B[N], F[N];
    
    int main() {
        Big_num_work.Init(A); Big_num_work.Init(B);
        int T = 0; Gcd(A, B, T);
        if(T == 0) Big_num_work.Out(A);
        else {
            int Tow[2]; Tow[0] = 1, Tow[1] = 2; F[0] = F[1] = 1; for(int i = 1; i <= T; i ++) Big_num_work.Mul(F, Tow);
            Big_num_work.Mul(A, F); Big_num_work.Out(A);
        }
        return 0;
    }
  • 相关阅读:
    vue-常用指令汇总
    vue-插槽和具名插槽
    vue-传值校验
    vue-动态组件
    vue-组件
    zend studio 快捷键收集
    php调试工具firephp
    zend studio插件
    MySQL各个版本区别
    PHP 中 Date 函数与实际时间相差8小时的解决方法
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9504190.html
Copyright © 2011-2022 走看看