zoukankan      html  css  js  c++  java
  • 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
    
     */
  • 相关阅读:
    linux的openfire运行日志配置经历
    基于Html5的兼容所有主流浏览器的在线视频播放器videoJs
    Eclipse下使用Fat Jar插件对源代码进行打包
    ubuntu下的openfire安装、配置、运行
    linux系统时间同步更新
    PRD产品需求文档概要
    oracle实现自动记录存储过程、自定义函数执行错误
    Oracler读取各种格式的相关日期格式
    linux中shell变量$#,$@,$0,$1,$2的含义解释
    Linux的五个查找命令
  • 原文地址:https://www.cnblogs.com/captain1/p/9781322.html
Copyright © 2011-2022 走看看