zoukankan      html  css  js  c++  java
  • bzoj1876[SDOI2009] SuperGCD

    题目链接:bzoj1876

    题目大意:

    就是求GCD。对于100%的数据,0 < A , B ≤ 10 ^ 10000。


    题解:

    高精度+更相减损术

    更相减损术就是设有两个数A,B

    首先判断A,B是否都是偶数,如果都是的话就一直除2,直到有某个数不是偶数为止。gcd(A,B)中2这个因子的个数就等于除2的次数。—— ①

    做完这一步的A,B就肯定不会再有2的因子了。

    所以如果A,B中有某个数是偶数,就不要大意的把它砍半直到为奇数。—— ②

    当两个都是奇数的时候就相减一下,重复这两个步骤(②③)。 —— ③

    ========================================

    这样的一道题做了我好久QAQ(%%更相减损术

    TLE完了WA一年!讲真,拍了巨久!嗨呀好气啊


    不过,好像还挺快的~

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    using namespace std;
    #define maxn 11000
    
    const int mod=100000000;
    struct node
    {
    	int a[1500],len;
    	node(){len=1;memset(a,0,sizeof(a));}
    }a,b;
    char s[maxn];
    void read(node &c)
    {
    	gets(s);
    	int t,i,len,now=0;
    	len=strlen(s);t=1;
    	for (i=len-1;i>=0;i--)
    	{
    		now=now+(s[i]-'0')*t;t*=10;
    		if ((len-i)%8==0) {c.a[c.len++]=now;now=0;t=1;}
    	}
    	if (now!=0) c.a[c.len++]=now;c.len--;
    }
    bool pz()
    {
    	if (a.len!=b.len) return false;
    	int i;
    	for (i=a.len;i>=1;i--)
    	 if (a.a[i]!=b.a[i]) return false;
    	return true;
    }
    bool comp()
    {
    	if (a.len>b.len) return true;
    	else if (a.len<b.len) return false;
    	int i;
    	for (i=a.len;i>=1;i--)
    	 if (a.a[i]>b.a[i]) return true;
    	 else if (a.a[i]<b.a[i]) return false;
    	return true;
    }
    void ct(node &c,node d)
    {
    	int i;
    	for (i=1;i<=c.len;i++)
    	{
    		if (c.a[i]>=d.a[i]) c.a[i]-=d.a[i];
    		else {c.a[i]=c.a[i]+mod-d.a[i];c.a[i+1]-=1;}
    	}
    	while (c.a[c.len]==0 && c.len>1) c.len--;
    }
    void diva()
    {
    	int i;
    	for (i=a.len;i>=1;i--)
    	{
    		if (a.a[i]&1) a.a[i-1]+=mod;
    		a.a[i]>>=1;
    	}
    	while (a.a[a.len]==0 && a.len>1) a.len--;
    }
    void divb()
    {
    	int i;
    	for (i=b.len;i>=1;i--)
    	{
    		if (b.a[i]&1) b.a[i-1]+=mod;
    		b.a[i]>>=1;
    	}
    	while (b.a[b.len]==0 && b.len>1) b.len--;
    }
    void multi()
    {
    	int i;
    	for (i=a.len;i>=1;i--)
    	{
    		a.a[i]<<=1;
    		if (a.a[i]>=mod) {a.a[i+1]++;a.a[i]-=mod;}
    	}
    	while (a.a[a.len+1]) a.len++;
    }
    void print()
    {
    	int i;
    	printf("%d",a.a[a.len]);
    	for (i=a.len-1;i>=1;i--)
    	  printf("%08d",a.a[i]);
    	printf("
    ");
    }
    int main()
    {
    	int tot=0;read(a);read(b);
    	while (!(a.a[1]&1) && !(b.a[1]&1)) {tot++;diva();divb();}
    	while (!(a.a[1]&1)) diva();
    	while (!(b.a[1]&1)) divb();
    	while (!pz())
    	{
    		if (comp()) ct(a,b);
    		else ct(b,a);
    		while (!(a.a[1]&1)) diva();
    		while (!(b.a[1]&1)) divb();
    	}
    	while (tot--) multi();
    	print();
    	return 0;
    }


  • 相关阅读:
    powerdesigner添加mysql的字符集ENGINE和DEFAULT CHARACTER SET
    powerdesigner怎么设置同时显示name和code
    更改gradle的java的class文件输出目录的结构
    使用TortoiseGit时如何实现SSH免密码登录
    TortoiseGit之配置密钥
    Mock InjectMocks ( @Mock 和 @InjectMocks )区别
    Centos tomcat jmx 远程连接
    【C++】常见易犯错误之数值类型取值溢出与截断(3)
    【C++】常见易犯错误之数值类型取值溢出与截断(2)
    【C++】常见易犯错误之数值类型取值溢出与截断(1)
  • 原文地址:https://www.cnblogs.com/Euryale-Rose/p/6527810.html
Copyright © 2011-2022 走看看