zoukankan      html  css  js  c++  java
  • HDU 4344

    其实不过是大整数分解。。。

    注意两点:注意L 不能==N

    但是,N却可以是素数。。。囧

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstdio>
    #define LL __int64
    #define MAX 1LL<<61
    #define Times 8
    #define N 501
    #define C 101
    using namespace std;
    LL cop[N];
    int ct;
    
    bool cmp(LL a,LL b){
    	if(a<b) return true;
    	return false;
    }
    
    LL gcd(LL a,LL b){
    	return b==0?a:gcd(b,a%b);
    }
    
    LL random(LL n){
    	return (LL)((double)rand()/RAND_MAX*n+0.5);
    }
    
    LL multi(LL a,LL b,LL m){   //a*b%m
    	LL ret=0;
    	while(b){
    		if(b&1)
    		ret=(ret+a)%m;
    		b>>=1;
    		a=(a<<1)%m;
    	}
    	return ret;
    }
    
    LL quick(LL a,LL b,LL m){
    	LL ans=1;
    	a%=m;
    	while(b){
    		if(b&1){
    			ans=multi(ans,a,m);
    			b--;
    		}
    		b/=2;
    		a=multi(a,a,m);
    	}
    	return ans;
    }
    
    bool Witness(LL a,LL n){
    	LL m=n-1;
    	int j=0;
    	while(!(m&1)){
    		j++;
    		m>>=1;
    	}
    	LL x=quick(a,m,n);
    	if(x==1||x==n-1)
    	return false;
    	while(j--){
    		x=multi(x,x,n);
    		if(x==n-1)
    		return false;
    	}
    	return true;
    }
    
    bool Miller_Rabin(LL n){
    	if(n<2) return false;
    	if(n==2) return true;
    	if(!(n&1)) return false;
    	for(int i=1;i<=Times;i++){
    		LL a=random(n-2)+1;
    		if(Witness(a,n)) return false;
    	}
    	return true;
    }
    
    LL Pollard_Rho(LL n,int c){
    	LL x,y,d,i=1,k=2;
    	x=random(n-1)+1;
    	y=x;
    	while(true){
    		i++;
    		x=(multi(x,x,n)+c)%n;
    		d=gcd(y-x,n);
    		if(d>1&&d<n){
    			return d;
    		}
    		if(y==x) return n;
    		if(i==k){
    			y=x;
    			k=k<<1;
    		}
    	}
    }
    
    void find(LL n,int k){
    	if(n==1) return ;
    	if(Miller_Rabin(n)){
    		cop[++ct]=n;
    		return ;
    	}
    	LL p=n;
    	while(p>=n)
    	p=Pollard_Rho(p,k--);
    	find(p,k);
    	find(n/p,k);
    }
    
    int main(){
    	int T;
    	LL n;
    	scanf("%d",&T);
    	while(T--){
    		scanf("%I64d",&n);
    		ct=0;
    		find(n,C);
    		sort(cop+1,cop+1+ct,cmp);
    		if(ct==1){
    			printf("1 1
    ");
    			continue;
    		}
    		LL cnt=0;LL tmp=0; LL ans=0;
    		cop[0]=1;
    		cop[++ct]=1;
    		for(int i=1;i<=ct;i++){
    			if(cop[i]!=cop[i-1]){
    				ans+=tmp;
    				tmp=cop[i];
    				cnt++;
    			}
    			else{
    				tmp*=cop[i];
    			}
    		}
    		if(ans==n)
    		ans/=cop[1];
    		printf("%I64d %I64d
    ",cnt-1,ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    删除 Visual studio 生成后的临时文件
    C# 中的委托和事件(转)
    C#复制DataRow出现“该行已经属于此表”错误的解决办法(转)
    ini配置文件读取类
    c# wpf窗体前端显示问题
    注册系统热键类(原创)
    C# 窗体最小化的托盘/系统通知区域(转)
    php explode()返回值
    $_SERVER['SCRIPT_NAME']
    svn合并初次使用心得
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/4143987.html
Copyright © 2011-2022 走看看