1876: [SDOI2009]SuperGCD(高精度+更相减损法求GCD)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1876

高精度的话辗转相除明显不靠谱,那么就用更相减损法来求最大公约数即可,然后练手一下高精度即可。

代码(压了9位的高精,跑得蛮快的):

include <cstdio>

include <algorithm>

include <cstring>

using namespace std ;

define rep( i , x ) for ( int i = 0 ; i ++ < x ; )

define REP( i , l , r ) for ( int i = l ; i <= r ; ++ i )

define DOWN( i , r , l ) for ( int i = r ; i >= l ; — i )

const int maxn = 1310 , maxb = 9 ;

int p[ maxb + 1 ] ;

inline void INIT( ) {

p[ 0 ] = 1 ; rep( i , maxb ) p[ i ] = p[ i - 1 ] * 10 ;

}

char s[ maxn * maxb ] ;

struct bignum {

int a[ maxn ] , n ;

 

bignum(  ) {

    memset( a , 0 , sizeof( a ) ) ;

}

 

inline void read(  ) {

    scanf( "%s" , s + 1 ) ;

    int len = strlen( s + 1 ) , val ;

    if ( len == 1 && s[ 1 ] == '0' ) a[ n = 1 ] = 0 ; else n = 0 ;

    for ( int i = len ; i > 0 ; i -= maxb ) {

        val = 0 ;

        if ( i >= maxb ) REP( j , ( i - maxb + 1 ) , i ) val = val * 10 + s[ j ] - '0'

        ; else rep( j , i ) val = val * 10 + s[ j ] - '0' ;

        a[ ++ n ] = val ;

    }

}

 

inline void write(  ) {

    printf( "%d" , a[ n ] ) ;

    DOWN( i , ( n - 1 ) , 1 ) {

        REP( j , 1 , ( maxb - 1 ) ) if ( a[ i ] <= p[ j ] ) printf( "0" ) ;

        printf( "%d" , a[ i ] ) ;

    }

    printf( "\n" ) ;

}

 

inline int cmp( const bignum &x ) {

    if ( n > x.n ) return 1 ; else if ( n < x.n ) return - 1 ;

    DOWN( i , n , 1 ) {

        if ( a[ i ] > x.a[ i ] ) return 1 ; else if ( a[ i ] < x.a[ i ] ) return - 1 ;

    }

    return 0 ;

}

 

inline void div2(  ) {

    DOWN( i , n , 1 ) {

        a[ i - 1 ] += ( a[ i ] & 1 ) * p[ maxb ] ; a[ i ] >>= 1 ;

    }

    if ( n > 1 && ! a[ n ] ) -- n ;

}

 

inline void mul2(  ) {

    rep( i , n ) a[ i ] <<= 1 ;

    rep( i , n ) if ( a[ i ] >= p[ maxb ] ) {

        a[ i + 1 ] += a[ i ] / p[ maxb ] ; a[ i ] %= p[ maxb ] ;

    }

    n += ( a[ n + 1 ] > 0 ) ;

}

 

inline void dec( const bignum &x ) {

    rep( i , n ) {

        for ( ; a[ i ] < x.a[ i ] ; a[ i ] += p[ maxb ] , -- a[ i + 1 ] ) ;

        a[ i ] -= x.a[ i ] ;

    }

    DOWN( i , n , 1 ) if ( a[ i ] ) {

        n = i ; break ;

    }

}

 

inline bool odd(  ) {

    return a[ 1 ] & 1 ;

}

 

inline bool check(  ) {

    return a[ 1 ] == 0 && n == 1 ;

}

} n1 , n2 , ans , temp ;

int cnt = 0 ;

int main( ) {

INIT(  ) ; n1.read(  ) ; n2.read(  ) ;

if ( n1.check(  ) ) {

    n2.write(  ) ; return 0 ;

}

if ( n2.check(  ) ) {

    n1.write(  ) ; return 0 ;

}

for ( int rec = n1.cmp( n2 ) ; rec ; rec = n1.cmp( n2 ) ) {

    if ( n1.odd(  ) ) {

        if ( n2.odd(  ) ) {

            if ( rec == 1 ) n1.dec( n2 ) ; else n2.dec( n1 ) ;

        } else n2.div2(  ) ;

    } else {

        if ( n2.odd(  ) ) n1.div2(  ) ; else ++ cnt , n1.div2(  ) , n2.div2(  ) ;

    }

}

ans = n1 ;

while ( cnt -- ) ans.mul2(  ) ;

ans.write(  ) ;

return 0 ;

}

    原文作者:AmadeusChan
    原文地址: https://www.jianshu.com/p/b9f3b115fa39#comments
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞