• POJ 3358


    此题的主要还是如何把小数化作分数来解答。

    设p/q。对于二进制(三进制,四进制一样),若p>q便商1,取mod,p*2-->p,然后再作p/q,若p<q,商0。

    于是有,在去公约数GCD后,p/q的小数是否重复,和上述步骤p是否重复是一致的。若重复,得方程

    p*2^i=p*2^j (mod q)。则有p*2^i(2^(j-i)-1)=0 (mod q)。即q|2^i(2^(j-i)-1)。而要求最小,只需使两者相等。即q中2的幂即为i。利用欧拉定理也可求出j-i的最小值。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #define LL __int64
    using namespace std;
    
    LL fac[10000]; int cnt;
    
    LL gcd(LL a,LL b){
    	if(b==0) return a;
    	return gcd(b,a%b);
    }
    
    LL Euler(LL m){
    	LL res=m;
    	LL k=(LL)sqrt((double)m);
    	for(LL i=2;i<=k;i++){
    		if(m%i==0){
    			res=res-res/i;
    			while(m%i==0)
    			m/=i;
    		}
    	}
    	if(m>1)
    	res=res-res/m;
    	return res;
    }
    
    LL quick(LL a,LL b,LL m){
    	LL ans=1;
    	while(b){
    		if(b&1){
    			ans=(ans*a)%m;
    		}
    		b>>=1;
    		a=(a*a)%m;
    	}
    	return ans;
    }
    
    int main(){
    	LL p,q;
    	int kase=0;
    	while(scanf("%I64d/%I64d",&p,&q)!=EOF){
    		p=p%q;
    		LL g=gcd(p,q);
    		p/=g; q/=g;
    		LL ai=0,aj=0;
    		while(q%2==0){
    			ai++;
    			q/=2;
    		}
    		LL phi=Euler(q);
    		cnt=0;
    		LL k=(LL)sqrt((double)phi);
    		for(LL i=1;i<=k;i++){
    			if(phi%i==0){
    				fac[cnt++]=i;
    				fac[cnt++]=phi/i;
    			}
    		}
    		sort(fac,fac+cnt);
    		for(int i=0;i<cnt;i++){
    			LL ans=quick((LL)2,fac[i],q);
    			if(ans==1){
    				aj=fac[i];
    				break;
    			}
    		}
    		printf("Case #%d: %I64d,%I64d
    ",++kase,ai+1,aj);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    jQuery的DOM操作
    jQuery的样式篇
    DOM对象控制HTML
    线程属性
    Glib动态加载模块(插件)
    linux 进程与线程命令
    error: server certificate verification failed.
    Qt qmake高级应用(翻译)
    Linux下设置QT环境变量
    pro、pri、prf、prl文件(qmake)
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/3968987.html
Copyright © 2020-2023  润新知