CF1033D Divisors Pollard-rho

好像卡常,第10个点一直TLE~

Code: 

#include <bits/stdc++.h>  
#define ll long long 
#define ull unsigned long long                                                               
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;    
set<ll>S; 
map<ll,int>pp;  
map<ll,int>::iterator it;
int Array[20]={2,3,5,7,11,13,17,19};       
ll mult(ll x,ll y,ll mod) 
{
    ll tmp=(long double)x/mod*y;  
    return ((ull)x*y-(ull)tmp*mod+(ull)mod)%mod; 
}
ll qpow(ll base,ll k,ll mod) 
{
    ll tmp=1; 
    for(;k;k>>=1,base=mult(base,base,mod)) 
        if(k&1) tmp=mult(tmp,base,mod); 
    return tmp; 
} 
int isprime(ll x) 
{ 
    if(x<=2) return 1; 
    int i,j,k; 
    ll cur,a,pre;   
    for(k=0,cur=x-1;cur%2==0;cur/=2) ++k; 
    for(i=0;i<8;++i) 
    {
        if(x==Array[i]) return 1;     
        a=pre=qpow(Array[i],cur,x);      
        for(j=1;j<=k;++j) 
        { 
            a=mult(a,a,x);       
            if(a==1&&pre!=1&&pre!=x-1) return 0;     
            pre=a; 
        }
        if(a!=1) return 0; 
    }
    return 1;   
} 
ll F(ll x,ll c,ll mod) 
{
    return (mult(x,x,mod)+c)%mod;  
}
ll pollard_rho(ll x) 
{
    int k,step; 
    ll s=0,t=0,c=rand()%(x-1)+1,val=1,d; 
    for(k=1;;k<<=1,s=t,val=1) 
    {
        for(step=1;step<=k;++step) 
        {
            t=F(t,c,x); 
            val=mult(val,abs(s-t),x);       
            if(step%127==0) 
            {
                d=__gcd(val,x);   
                if(d>1) return d; 
            }
        }
        d=__gcd(val,x); 
        if(d>1) return d;    
    }
}       
void solve(ll x) 
{
    if(isprime(x)) 
    {
        S.insert(x); 
        return; 
    } 
    ll p=x; 
    for(;p>=x;) p=pollard_rho(x); 
    for(;x%p==0;) x/=p; 
    solve(x),solve(p);   
}
set<ll>::iterator l; 
int main() 
{
    int i,j,n; 
    // setIO("input");  
    srand((unsigned)time(NULL));              
    scanf("%d",&n); 
    for(i=1;i<=n;++i) 
    {
        ll a; 
        S.clear(),scanf("%lld",&a),solve(a);   
        for(l=S.begin();l!=S.end();l++)
        { 
            if((*l)==1) continue;       
            for(;a%(*l)==0;) 
            {
                a/=(*l), pp[(*l)]++;              
            }
        }
    }
    ll re=1; 
    for(it=pp.begin();it!=pp.end();it++) 
        re=mult(re,(it->second+1),998244353);         
    printf("%I64d\n",re);   
    return 0; 
}

  

posted @ 2019-09-13 10:40  EM-LGH  阅读(224)  评论(0编辑  收藏  举报