zoukankan      html  css  js  c++  java
  • #Pollard-Rho,高精度#洛谷 3499 [POI2010]NAJ-Divine Divisor

    题目

    给定(m)个数(a_i),令(n=prod_{i=1}^m a_i)
    问有多少个大于1的正整数(d)满足(d^{max k}|n)
    并输出(max k)(mleq 600,a_ileq 10^{18})


    分析

    (a_i)质因数分解,(n)的指数累加,那么就可以使(n)质因数分解,
    若有(p)个质数使得(p^{max k}|n)(d)的个数为(2^p-1)
    由于(pleq 600),所以要高精度乘法


    代码

    #include <cstdio>
    #include <cctype>
    #include <cmath>
    #include <cstdlib>
    #include <map>
    #define rr register
    using namespace std;
    const double ha=pow(11.0,19/17.0);
    const int prime[8]={2,61,97,7,13,17,23,29},MOD=1000000000;
    typedef long long lll; lll x,n,tot,mx,ans,p[41],dig[211];
    map<lll,int>uk; map<lll,int>::iterator it;
    inline lll iut(){
    	rr lll ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans; 
    }
    inline lll mo(lll a,lll b,lll mod){return a+b>=mod?a+b-mod:a+b;}
    inline lll mul(lll a,lll b,lll mod){return (a*b-(lll)((long double)a/mod*b)*mod+mod)%mod;}
    inline lll gcd(lll a,lll b){return b?gcd(b,a%b):a;}
    inline lll ksm(lll x,lll y,lll mod){
    	rr lll ans=1;
    	for (;y;y>>=1,x=mul(x,x,mod))
    	    if (y&1) ans=mul(ans,x,mod);
    	return ans;
    }
    inline bool mr(lll n){
    	if (n==1) return 0;
    	for (rr int i=0;i<8;++i)
    	    if (n==prime[i]) return 1;
    	for (rr int i=0;i<8;++i)
    	    if (n%prime[i]==0) return 0;
        rr lll m=n-1; rr int cnt=0;
        while (!(m&1)) m>>=1,++cnt;
    	for (rr int i=0;i<8&&prime[i]<n;++i){
    		rr lll now=ksm(prime[i],m,n),ls=now;
    		for (rr int j=1;j<=cnt;++j){
    			now=mul(now,now,n);
    			if (now==1&&ls!=1&&ls!=n-1) return 0;
    			ls=now;
    		}
    		if (now!=1) return 0;
    	} 
    	return 1;
    }
    inline lll rho(lll n,lll h){
    	if (!(n&1)) return 2;
    	if (!(n%3)) return 3;
    	rr lll x1=(rand()+1)%n,x2=x1,p=1;
    	for (rr int k=2;;k<<=1,x2=x1,p=1){
    		for (rr int i=1;i<=k;++i){
    			x1=mo(mul(x1,x1,n),h,n);
    			p=mul(p,x1>x2?x1-x2:x2-x1,n);
    			if (!(i&127)){
    				rr lll d=gcd(p,n);
    				if (d>1) return d;
    			}
    		}
    		rr lll d=gcd(p,n);
    		if (d>1) return d;
    	}
    }
    inline void dfs(lll n){
    	if (n==1) return;
    	if (mr(n)){
    		p[++tot]=n;
    		return;
    	}
    	rr lll t=n;
    	while (t==n) t=rho(n,rand()%(n-1)+1);
    	while (!(n%t)) n/=t;
    	dfs(t),dfs(n);
    }
    inline void cheng(int t){
    	rr lll s=0,g=0;
    	for (rr int i=1;i<=dig[0];++i)
    	    s=dig[i]*t+g,g=s/MOD,dig[i]=s%MOD;
    	if (g) dig[++dig[0]]=g;
    }
    signed main(){
    	n=iut(),srand((unsigned)((lll)(new char)*ha));
    	for (rr int i=1;i<=n;++i){
    		tot=0,dfs(x=iut());
    		for (rr int i=1;i<=tot;++i){
    			rr int c=0;
    			while (x%p[i]==0) x/=p[i],++c;
    			uk[p[i]]+=c;
    		}
    	}
    	for (it=uk.begin();it!=uk.end();++it)
    	if (mx<it->second) mx=it->second,ans=1;
    		else if (mx==it->second) ++ans;
    	dig[dig[0]=1]=1;
    	for (rr int i=1;i<=ans/25;++i) cheng(33554432);
    	if (ans%25) cheng(1<<(ans%25));
    	--dig[1],printf("%lld
    ",mx);
    	printf("%lld",dig[dig[0]]);
    	for (rr int i=dig[0]-1;i;--i) printf("%09lld",dig[i]);
    	return 0;
    }
    
  • 相关阅读:
    ArcEngine 地图与布局的联动
    ArcGIS Server安装篇
    AO+C#设置栅格图层基高 制作三维
    ArcGIS 10研究(一) 之 Desktop总体介绍 转载
    linux centos7 增加硬盘
    linux CentOS7安装oracle12c
    java中关于Socket类通信的基本测试程序
    Ubuntu 的中国梦
    我们无需“开始”菜单
    数据库战略高度解析 之系列说明
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14602374.html
Copyright © 2011-2022 走看看