SDOI2009 SuperGCD

Posted captain1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SDOI2009 SuperGCD相关的知识,希望对你有一定的参考价值。

传送门

这题简直了……(虽然说python可以直接过,但是你考试的时候也只是能拿python对拍而不是交上去……)

这题直接用更相减损术会T掉(我们不可能还用高精除法,因为数这么长的话高精除法的效率很低),但是直接更相减损也会T……即使压位都不行,但是有一位dalao压位就过了,而我就T了……

于是学了一波更相减损的优化,大意如下:

若A,B同时为偶数,那么gcd(A,B) = gcd(A/2,B/2)* 2。

否则的话,我们把是偶数的那个数/2继续算gcd即可。

但是你真的觉得代码有这么简单吗……?毕竟高精是不可能的——冷某

好吧其实应该练练高精模板怎么写了orz……这次又抄了代码。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<queue>
#define pr pair<int,int>
#define mp make_pair
#define fi first
#define sc second
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar(‘
‘)

using namespace std;
typedef long long ll;
const int M = 20005;
const int base = 1e9;

int read()
{
    int ans = 0,op = 1;
    char ch = getchar();
    while(ch < 0 || ch > 9)
    {
    if(ch == -) op = -1;
    ch = getchar();
    }
    while(ch >= 0 && ch <= 9)
    {
    ans *= 10;
    ans += ch - 0;
    ch = getchar();
    }
    return ans * op;
}

char d[M];
int cnt;

struct big
{
    int len,s[M];
    big()
    {
    len = 0;
    memset(s,0,sizeof(s));
    }
    big operator - (const big &g) const
    {
    big c;
    c.len = max(len,g.len);
    rep(i,0,c.len-1) c.s[i] = s[i] - g.s[i];
    rep(i,0,c.len-1) if(c.s[i] < 0) c.s[i+1]--,c.s[i] += 10;
    while(!c.s[c.len-1]) c.len--;
    return c;
    }
    bool operator < (const big &g) const
    {
    if(len != g.len) return len < g.len;
    per(i,len-1,0) if(s[i] != g.s[i]) return s[i] < g.s[i];
    return 0;
    }
    bool operator == (const big &g)
    {
    if(len != g.len) return 0;
    per(i,len-1,0) if(s[i] != g.s[i]) return 0;
    return 1;
    }
    void read()
    {
    scanf("%s",d);
    len = strlen(d);
    per(i,len-1,0) s[i] = d[len-i-1] - 0;
    }
    void print()
    {
    per(i,len-1,0) printf("%d",s[i]);enter;
    }
}a,b,c;

bool check(big a)
{
    int x = a.s[0];
    return !(x & 1);
}

big div(big a)
{
    per(i,a.len-1,1) a.s[i-1] += (a.s[i] & 1) * 10,a.s[i] >>= 1;
    a.s[0] >>= 1;
    while(!a.s[a.len-1]) a.len--;
    return a;
}

big mul(big a)
{
    int cur = 0;
    rep(i,0,a.len-1)
    {
    a.s[i] = (a.s[i] << 1) + cur;
    cur = 0;
    if(a.s[i] >= 10)
    {
        cur = a.s[i] / 10,a.s[i] %= 10;
        if(i == a.len - 1) a.len++;
    }
    }
    return a;
}

int main()
{
    a.read(),b.read();
    //a.print(),b.print();
    while(!(a == b))
    {
    if(a < b) swap(a,b);
    int p1 = check(a),p2 = check(b);
    if(p1 && p2) cnt++,a = div(a),b = div(b);
    else if(p1) a = div(a);
    else if(p2) b = div(b);
    else a = a - b;
    }
    rep(i,1,cnt) a = mul(a);
    a.print();
    return 0;
}
/*
437534975 34759347589347589347589

 */

 

以上是关于SDOI2009 SuperGCD的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1876: [SDOI2009]SuperGCD

bzoj1876 [SDOI2009]SuperGCD

P2152 [SDOI2009]SuperGCD(模拟)

BZOJ1876: [SDOI2009]SuperGCD

P2152 [SDOI2009]SuperGCD

[SDOI2009]SuperGCD