zoukankan      html  css  js  c++  java
  • LightOJ

    思路:

    用Pollard_Rho做质因子分解,dfs枚举所有因子判断是否合法;
    由于当(b*b>a)时一定无解,因此这里还可以提前判断一下;
    我看其他题解的做法基本都是枚举素数做质因子分解(1E6以内素数有78498个),而(Test)是4e3组,这复杂度已经很高了,更离谱的是有人枚举1-b(b<1e6) ;

    代码:

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    using namespace std;
    typedef __int128 LL;
    typedef unsigned long long uLL;
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pLL;
    typedef pair<double,double> pdd;
    const int N=1e5+5;
    const int M=4e4+5;
    const int inf=0x3f3f3f3f;
    const int mod=1e9+7;
    const double eps=1e-8;
    const double pi=acos(-1.0);
    const int S=100;
    #define ls (i<<1)
    #define rs (i<<1|1)
    #define fi first
    #define se second
    #define pb push_back
    #define eb emplace_back
    #define mk make_pair
    #define mem(a,b) memset(a,b,sizeof(a))
    LL read()
    {
        LL x=0,t=1;
        char ch;
        while((ch=getchar())<'0'||ch>'9') if(ch=='-') t=-1;
        while(ch>='0'&&ch<='9'){ x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); }
        return x*t;
    }
    std::mt19937 rnd(233);
    LL factor[N];
    int tot;
    LL gcd(LL x,LL y)
    {
        return y?gcd(y,x%y):x;
    }
    
    inline LL mul(LL a,LL b,LL p)
    {
        return a*b%p;
    }
    
    //LL mul(LL a,LL b,LL p)
    //{
    //    LL res=0;
    //    while(b)
    //    {
    //        if(b&1) res=(res+a)%p;
    //        a=(a+a)%p;
    //        b>>=1;
    //    }
    //    return res;
    //}
    inline LL power(LL a,LL b,LL p)
    {
        LL res=1;
        while(b)
        {
            if(b&1) res=mul(res,a,p);
            a=mul(a,a,p);
            b>>=1;
        }
        return res;
    }
    inline bool check(LL a,LL n,LL d,LL cnt)
    {
        LL res=power(a,d,n);
        LL las=res;
        for(int i=1;i<=cnt;i++)
        {
            res=mul(res,res,n);
            if(res==1&&las!=1&&las!=n-1) return 1;
            las=res;
        }
        if(res!=1) return 1;
        return 0;
    }
    bool MR(LL n)
    {
        if(n<2) return 0;
        if(n==2) return 1;
        if((n&1)==0) return 0;
        LL d=n-1,cnt=0;
        while((d&1)==0) d>>=1,cnt++;
        for(int i=1;i<=S;i++)
        {
            LL a=rnd()%(n-1)+1;
            if(check(a,n,d,cnt)) return 0;
    
        }
        return 1;
    }
    LL PR(LL n,LL k)
    {
        LL u=2,v=1;
        LL x=rnd()%(n-1)+1;
        LL y=x;
        while(1)
        {
            x=(mul(x,x,n)+k)%n;
            v++;
            LL d=gcd((y-x+n)%n,n);
            if(d>1&&d<=n) return d;
            if(v==u)
            {
                y=x;
                u<<=1;
            }
        }
    }
    void divide(LL n,LL k)
    {
        if(n==1) return ;
        if(MR(n)) return (void)(factor[++tot]=n);
        LL d=n,c=k;
        while(d==n) d=PR(n,--c);
        divide(d,c);
        divide(n/d,c);
    }
    long long ans;
    LL a,b;
    LL c[N],cnt[N];
    void dfs(int len,LL x)
    {
        //printf("%d , %lld
    ",len,x);
        if(len==0){
            if(min(x,a/x)>=b&&x!=a/x) ans++;
            return ;
        }
        dfs(len-1,x);
        for(int i=1;i<=cnt[len];i++)
        {
            x*=c[len];
            dfs(len-1,x);
        }
    }
    int main()
    {
        int T=read();
        int cas=0;
        while(T--)
        {
            ans=tot=0;
            a=read(),b=read();
            divide(a,S);
            sort(factor,factor+1+tot);
            for(int i=1;i<=tot;i++) c[i]=factor[i];
            unique(c+1,c+tot+1);
            int len=0;
            for(int i=1;i<=tot;i++)
            {
                if(factor[i]!=factor[i-1]) len++;
                cnt[len]++;
            }
            dfs(len,1);
            for(int i=1;i<=len;i++) cnt[i]=0;
            printf("Case %d: %lld
    ",++cas,ans>>1);
        }
        return 0;
    }
    /*
    20
    1000000000000 2
    963761198400 5
    963761198400 5
    963761198400 5
    963761198400 5
    1000000000000 2
    963761198400 5
    963761198400 5
    963761198400 5
    963761198400 5
    1000000000000 500000
    963761198400 5
    963761198400 5
    963761198400 5
    963761198400 100
    */
    

    附一张因子个数图,前者为因子最多的数字,后者为其因子数量;(源自知乎)

  • 相关阅读:
    Android Push Notification实现信息推送使用
    java动态编译
    Directx11教程(56) 建立一个skydome
    Directx11教程(51) 简单的billboard
    Directx11教程(52) 实例(instancing)的简单应用
    Directx11教程(50) 输出depth/stencil buffer的内容
    Directx11教程(54) 简单的基于GS的billboard实现
    Directx11教程(57) 环境映射
    Directx11教程(59) tessellation学习(1)
    Directx11教程(20) 一个简单的水面
  • 原文地址:https://www.cnblogs.com/DeepJay/p/15173774.html
Copyright © 2011-2022 走看看