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的主要内容,如果未能解决你的问题,请参考以下文章