为什么NKOJ的题交JAVA会被keyword卡System,还不能用python水高精度……
题目分析
回归正题,由于本题数据范围 0 ≤ A , B ≤ 1 0 10000 0 \le A,B \le 10^{10000} 0≤A,B≤1010000两个 10000 10000 10000位的整数算GCD,所以用高精度欧几里得GCD的话会使得算法时间复杂度不够优秀(虽然各位Dalao都会卡常过题,但本蒟蒻还是希望给大家带来较好的算法)
这里为了可以更有惊无险的AC本题,我采用了辗转相除Pro优化法,其内容如下:(可能是环境不一样,在另外一边看起来很好看,粘过来难看死了)
 
     
      
       
        
         
          g
         
         
          c
         
         
          d
         
        
        
         (
        
        
         a
        
        
         ,
        
        
         b
        
        
         )
        
        
         =
        
        
         
          {
         
         
          
           
            
             
              
               a
              
              
                  
              
              
               [
              
              
               a
              
              
               =
              
              
               b
              
              
               ]
              
              
                                                    
              
             
            
           
          
          
           
            
             
              
               
                g
               
               
                c
               
               
                d
               
              
              
               (
              
              
               b
              
              
               ,
              
              
               a
              
              
               )
              
              
                  
              
              
               [
              
              
               a
              
              
               <
              
              
               b
              
              
               ]
              
              
                                        
              
             
            
           
          
          
           
            
             
              
               
                g
               
               
                c
               
               
                d
               
              
              
               (
              
              
               a
              
              
               ,
              
              
               
                b
               
               
                2
               
              
              
               )
              
              
                  
              
              
               [
              
              
               a
              
              
               奇数
              
              
               b
              
              
               偶数
              
              
               ]
              
              
                          
              
             
            
           
          
          
           
            
             
              
               
                g
               
               
                c
               
               
                d
               
              
              
               (
              
              
               
                a
               
               
                2
               
              
              
               ,
              
              
               b
              
              
               )
              
              
                  
              
              
               [
              
              
               a
              
              
               偶数
              
              
               b
              
              
               奇数
              
              
               ]
              
              
                          
              
             
            
           
          
          
           
            
             
              
               
                g
               
               
                c
               
               
                d
               
              
              
               (
              
              
               
                a
               
               
                2
               
              
              
               ,
              
              
               
                b
               
               
                2
               
              
              
               )
              
              
               ×
              
              
               2
              
              
                  
              
              
               [
              
              
               a
              
              
               ,
              
              
               b
              
              
               均为偶数
              
              
               ]
              
              
                  
              
             
            
           
          
          
           
            
             
              
               
                g
               
               
                c
               
               
                d
               
              
              
               (
              
              
               a
              
              
               −
              
              
               b
              
              
               ,
              
              
               b
              
              
               )
              
              
               ;
              
              
                  
              
              
               [
              
              
               a
              
              
               ,
              
              
               b
              
              
               均为奇数
              
              
               ]
              
              
                   
              
             
            
           
          
         
        
       
       
        \mathrm{gcd}(a,b)= \left\{\begin{matrix} a \ \ \ [a=b]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\ \mathrm{gcd}(b,a)\ \ \ [a<b]\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\ \mathrm{gcd}(a,\frac{b}{2})\ \ \ [a奇数b偶数]\ \ \ \ \ \ \ \ \ \ \ \\ \mathrm{gcd}(\frac{a}{2},b)\ \ \ [a偶数b奇数]\ \ \ \ \ \ \ \ \ \ \ \\ \mathrm{gcd}(\frac{a}{2},\frac{b}{2}) \times 2\ \ \ [a,b均为偶数]\ \ \ \\ \mathrm{gcd}(a-b,b);\ \ \ [a,b均为奇数]\ \ \ \ \end{matrix}\right. 
       
      
     gcd(a,b)=⎩
              ⎨
              ⎧a   [a=b]                                     gcd(b,a)   [a<b]                         gcd(a,2b)   [a奇数b偶数]           gcd(2a,b)   [a偶数b奇数]           gcd(2a,2b)×2   [a,b均为偶数]   gcd(a−b,b);   [a,b均为奇数]    
但是很明显,我们的代码并不能用函数实现,这样就会MLE掉(函数递归的本质是压栈,当调用次数过多栈会原地爆炸),所以我们需要把这个转化为循环,在循环中又两个变量(高精度数)a,b,分别记录当前的两个数a,b,当找到a==b时,就直接break输出a的值;
注意,本体难点在于实现:高精需压位,输出需补0,若是忘了写,WA两行泪;(我的WA40pts就是没有补0造成的,TLE70pts就是用了递归+没有压位)
听着是不是很简单,当你实现的时候就知道什么叫坐牢了
 
 注意以下代码不知道为什么只过得了NKOJ的测试点,LUOGU和POJ的OIER们请移步其他文章或自己尝试去写;
AC-NKOJ Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
vector<int> a,b;
int kkk=1;
int cmp(vector<int> x,vector<int> y){
    if(x.size()!=y.size()){
		if(x.size()>y.size()){return 1;}
		else{return 0;}
	}
    for(int i=x.size()-1;i>=0;i--){
        if(x[i]!=y[i]){
			if(x[i]>y[i]){return 1;}
			else{return 0;} 
		}
    }
    return 3;
}
vector<int> sub(vector<int> a,vector<int> b){
    int k=0;
    vector<int> c;
    for(int i=0;i<a.size();i++){
        k+=a[i];
        if(i<b.size()){
            k-=b[i];
        }
        c.push_back((k+100000000)%100000000);
        if(k<0){
            k=-1;
        }else{
            k=0;
        }
    }
    while(c.size() > 1 && c.back()==0){
        c.pop_back();
    }
    return c;
}
vector<int> div(vector<int> a,int b){
    int k=0;
    vector<int> c;
    for(int i=a.size()-1;i>=0;i--){
        k=k*100000000+a[i];
        c.push_back(k/b);
        k%=b;
    }
    reverse(c.begin(),c.end());
    while(c.size()>1&&c.back()==0){
        c.pop_back();
    }
    return c;
}
vector<int> mul(vector<int> a , int b){
    int t=0;
    vector<int> c;
    for(int i=0;i<a.size();i++){
        t+=a[i]*b;
        c.push_back(t%100000000);
        t/=100000000;
    }
    while(t){
        c.push_back(t%100000000);
        t/=100000000;
    }
    while(c.size()>1&&c.back()==0){
        c.pop_back();
    }
    return c;
}
signed main(){
	string ch1,ch2;
	cin>>ch1>>ch2;
	int j=0,sum=0,t=1;
    for(int i=ch1.size()-1;i>=0;i--){
        j++;
        sum=sum+t*(ch1[i]-'0');
        t*=10;
        if(j==8||i==0){
            a.push_back(sum);
            j=0;
            t=1;
            sum=0;
        }
        
    }
    j=0,sum=0,t=1;
    for(int i=ch2.size()-1;i>=0;i--){
        j++;
        sum=sum+t*(ch2[i]-'0');
        t*=10;
        if(j==8||i==0){
            b.push_back(sum);
            j=0;
            sum=0;
            t=1;
        }
    }
	while(1){
		int k=cmp(a,b);
//		for(int i=a.size()-1;i>=0;i--){printf("%lld",a[i]);}
//		printf("\n");
//		for(int i=b.size()-1;i>=0;i--){printf("%lld",b[i]);}A
//		printf("\nssss\n");
// Debug
		if(!k){a.swap(b);}
		if(k==3){
			a=mul(a,kkk);
			printf("%lld",a[a.size()-1]);
			if(a.size()>1){
				for(int i=a.size()-2;i>=0;i--){printf("%08lld",a[i]);}
			}
            return 0;
		}
        
        int numa=a[0]%2;
        int numb=b[0]%2;
        vector<int> m,n;
        if(numa){
            if(numb){
                m=sub(a,b);
                n=b;
            }else{
				m=a;
				n=div(b,2);
			}
        }else{
			if(numb){
                m=div(a,2);
                n=b;
            }else{
				m=div(a,2);
				n=div(b,2);
				kkk*=2;	
			}
		}
		a=m;b=n;
	}
	return 0;
}
【还望各位dalao给蒟蒻一个赞】



















