高精度GCD
https://www.luogu.org/problemnew/show/P2152是一道模板题,因为不会phython,所以・・・只能老老实实写高精度。这里我们用到更相减损法求公约数。
看
首先,根据上面的步骤,分析他们是否是偶数,所以需要检查每个大数的最后一位;直到两个都是奇数,然后用大数减去小数,减去之后再重复之前的操作,然后把最后的数乘上若干个2就可以了;
分析操作过程,我们需要处理高精度判断奇偶数,高精度乘2,高精度除2,高精度减法这四个操作。
自己也是看了网上很多代码,然后照猫画虎,能改进的地方有很多。
高精度判断奇偶数
bool judge(const node &a) { return a.num[0]%2==0?//判断最后一位就好 }
高精度乘2
node mul2(node a) { int in=0; for(int i=0;i<a.len;i++) { a.num[i]=a.num[i]*2+in; in=0; if(a.num[i]>=10) { in=a.num[i]/10; a.num[i]%=10; if(i==a.len-1) a.len++; } } return a; }
高精度除2
node div2(node a) { for(int i=a.len-1;i>=1;i--)//这里是1,0的话会出现a.num[-1]的情况 { a.num[i-1]+=a.num[i]%2*10;//这一步可以自己去运算试试就明白了,运算的时候数是反过来的//反了两次就变正序了 a.num[i]/=2; } a.num[0]/=2; while(a.num[a.len-1]==0)a.len--;//去除前导0 return a; }
高精度减法
struct node { ll num[maxn],len; void clear()//清空一个node类型 { memset(num,0,sizeof(num)); len=0; return ; } node operator - (const node &a)重载 - 号,变成高精度减法 { big a1; a1.clear(); a1.len=max(a1.len,len); fin(0,a1.len-1) { a1.num[i]+=(num[i]-a.num[i]);//从个位减,不够则从上面一位取 if(a1.num[i]<0) { a1.num[i]+=10; a1.num[i+1]--; } } return a1; } node operator <(const node &a)//重载<号,因为一会儿要比较大小 { if(a.len!=len)return len<a.len; for(int i=len-1;i>=0;i--) { if(a.num[i]!=num[i])return num[i]<a.num[i]; } return false; } node operator ==(const node &a)//判断两个是否相等,相等则得到结果 { if(a.len!=len)return false; fin(0,a.len-1)if(a.num[i]!=num[i])return false; return true; } };
完整代码
#include<bits/stdc++.h> using namespace std; #define fin(a,n) for(int i=a;i<=n;i++) #define ll long long int const int maxn=1e4+27; struct node { int num[maxn],len; void clear() { memset(num,0,sizeof(num)); len=0; return ; } node operator - (const node &a) { node a1; a1.clear(); a1.len=max(a1.len,len); fin(0,a1.len-1) { a1.num[i]+=(num[i]-a.num[i]); if(a1.num[i]<0) { a1.num[i]+=10; a1.num[i+1]--; } } return a1; } bool operator <(const node &a) { if(a.len!=len)return len<a.len; for(int i=len-1;i>=0;i--) { if(a.num[i]!=num[i])return num[i]<a.num[i]; } return false; } bool operator ==(const node &a) { if(a.len!=len)return false; fin(0,a.len-1)if(a.num[i]!=num[i])return false; return true; } }; bool judge(const node &a) { return a.num[0]%2==0; } node mul2(node a) { int in=0; for(int i=0;i<a.len;i++) { a.num[i]=a.num[i]*2+in; in=0; if(a.num[i]>=10) { in=a.num[i]/10; a.num[i]%=10; if(i==a.len-1) a.len++; } } return a; } node div2(node a) { for(int i=a.len-1;i>=1;i--) { a.num[i-1]+=a.num[i]%2*10; a.num[i]/=2; } a.num[0]/=2; while(a.num[a.len-1]==0)a.len--; return a; } int main() { char s[maxn]; char ss[maxn]; scanf("%s %s",s,ss); int cnt2=0; node s1,s2; bool js1,js2; s1.len=strlen(s); fin(0,s1.len-1)s1.num[i]=s[s1.len-1-i]-'0'; s2.len=strlen(ss); fin(0,s2.len-1)s2.num[i]=ss[s2.len-1-i]-'0'; while(!(s1==s2))//下面就是更相减损法 { if(s1<s2)swap(s1,s2); js1=judge(s1); js2=judge(s2); if(js1&&js2) { s1=div2(s1); s2=div2(s2); cnt2++;//两个都为偶数,2的指数就+1 } else if(js1)s1=div2(s1);//一个为偶数,指数不加,直接除 else if(js2)s2=div2(s2); else s1=s1-s2;//都为奇数,大减小。 } fin(1,cnt2)s1=mul2(s1); for(int i=s1.len-1;i>=0;i--)printf("%d",s1.num[i]); return 0; }
实际上当a,b,为偶数时gcd(a,b)==2*gcd(a/2,b/2);
数论持续更新
文章来源: https://blog.csdn.net/weixin_44203780/article/details/88852389