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;
    }


  • 相关阅读:
    Bundle savedInstanceState的作用
    仿知乎程序 fragment的切换以及toolbar在不同页面下显示的menu不同
    LayoutInflater的inflate函数用法详解
    ListView之BaseAdapter的使用
    Android实现Banner界面广告图片循环轮播(包括实现手动滑动循环)
    Android中的onActivityResult和setResult方法的使用
    Gson解析复杂的json数据
    Android Volley入门到精通:定制自己的Request
    Android Volley入门到精通:使用Volley加载网络图片
    Android Volley入门到精通:初识Volley的基本用法
  • 原文地址:https://www.cnblogs.com/Euryale-Rose/p/6527810.html
Copyright © 2011-2022 走看看