zoukankan      html  css  js  c++  java
  • ALADDIN AND THE FLYING CARPET

    https://vjudge.net/contest/70017#problem/C

    题目大意:有T组数据,每组数据给两个数n,m,如果n=a*b,求min(a,b)大于等于m这样数对的个数 (a,b)<==>(b,a)

    暴力很容易想,直接枚举m~sqrt n看是否能被整除,m>sqrt n 则输出0,但是这样会超时。。(我怎么算着正解和暴力复杂度差不多??

    根据算术基本定理

    若n=p1^a1*p2^a2...pn^an则n的因子个数为(a1+1)*(a2+1)...*(an+1),所以我们只要求出小于m这样数对的个数再用总数减就行了,

    素数筛的时候会发现如果筛1~1e12范围的全部素数是做不到的,经证明我们只用筛1~1e6 即可:

    证明:

    假设 n=a*b (a<sqrt n< b <n )如果 b不是质数,则b=c*d (c<sqrt b<d <b)

    以此类推,最后大于sqrt n 的因数最多有一个,其余的都小于sqrt n,

    也就是说我们分解质因数后剩余的值(temp)判断一下,若temp大于1 说明 temp是大于sqrt n的质数 sum*=2即可,否则说明 全部因数都在1~1e6的范围

    #include<bits/stdc++.h> 
    using namespace std;
    const long long N=1e6+5;
    long long T,n,ans,tot,m,k,ss[N],sum;
    bool use[N];
    void pd()
    {
        use[1]=1;
        for(int i=2;i<=N-3;i++)
        {
            if(use[i]==0)
                ss[++k]=i;
            for(int j=1;j<=k&&ss[j]*i<=N-3;j++)
            {
                use[i*ss[j]]=1;
                if(i%ss[j]==0)
                    break;
            }
        }
    }
    int main()
    {
        pd();
        scanf("%lld",&T);
        for(int l=1;l<=T;l++)
        {
            ans=0;
            sum=1;
            tot=0;
            scanf("%lld %lld",&n,&m);
            long long temp=n;
            for(int i=1;i<=k&&ss[i]<=temp;i++)
            {
                tot=0;
                while(temp%ss[i]==0)
                {
                    temp/=ss[i];
                    tot++;
                }
                sum*=(tot+1);
                //printf("###%d %lld %lld
    ",i,ss[i],tot);
            }
            if(temp>1)
                sum*=2;
            //printf("%lld
    ",sum);
            for(int i=1;i<=sqrt(n)&&i<m;i++)//因数小于m的个数 
            {
                if(n%i==0)
                {
                    ans++;
                }
            }
            //printf("%lld
    ",sum);
            printf("Case %d: %lld
    ",l,(sum-ans*2)/2);
        }
    }

  • 相关阅读:
    装饰器
    函数的初识
    python的文件操作
    深浅copy
    set集合,是一个无序且不重复的元素集合
    基础数据类型 :字典
    列表的增删改查
    易错点 默认参数陷阱
    js中Array对象常用方法
    printf用法demo
  • 原文地址:https://www.cnblogs.com/cherrypill/p/12533439.html
Copyright © 2011-2022 走看看