hdu-5750-Dertouzos-数学

来源:互联网 发布:java接口自动化框架 编辑:程序博客网 时间:2024/06/01 19:24


题意:在【2,n-1】里找出有多少个数,使得 该数的最大“约数”为d,

这里约数不包括自身。


设该数为y,y=xd<=n  首先x<=floor【(n-1)/d】,然后可以发现,x一定是y的一个最小质因子,否则d可以更大,然后x还要小于等于d的最小质因子,否则d也可以更大,


也就是x<=min(floor((n-1)/d),d的最小质因子)  ,   d的最小质因子肯定不超过sqrtn级别的,然后可以打出sqrt(1e9)的素数表(大约3400个),然后暴力找


另一种是, 

素筛法打biao【i】到1e6,代表i的最小素因子

则ans=min(biao[i],(n-1)/d),在prim二分找一下多少个比它小即可

当n>1e6,min的第一个参数会不超过1000,直接暴力


代码1:

#include <iostream>#include <cstdio>#include <cmath>#include <string>#include <cstring>#include <cstdlib>#include <algorithm>using namespace std;const int N = 31622+2;bool f[N+50];int prim[N];int biao[N+50];int main(){    int ok=0;    //素数打表    f[1]=true;    for (long long i=2; i<=N; i++)  //1处    {        if (f[i]==false)           //优化        {            prim[++ok]=i;            for (long long j= i*i; j<=N; j=j+i) // 如果1处用1000必须_int64强制转换            {                f[j]=true;            }        }    }  /*  for (int i=1; i<=ok; i++)    {        biao[prim[i]]=prim[i];        for (long long j= (long long)prim[i]*prim[i]; j<=1e6; j=j+prim[i])        {            if (0==biao[j])                biao[j]=prim[i];        }    }*/    int n, a, d;    int t;    cin>>t;    while(t--)        // while(scanf("%d", &n)!=EOF)    {        scanf("%d%d",&n,&d);            int cun=0;            for (int i=1; i<=ok; i++)            {                if (1LL*prim[i]*d<=n) cun++;                else break;                if (d%prim[i]==0)break;            }            printf("%d\n",cun);    }    return 0;}


代码2:

#include <iostream>#include <cstdio>#include <cmath>#include <string>#include <cstring>#include <cstdlib>#include <algorithm>using namespace std;const int N = 1e6+2;bool f[N+50];int prim[N];int biao[N+50];int main(){    int ok=0;    //素数打表    f[1]=true;    for (long long i=2; i<=N; i++)  //1处    {        if (f[i]==false)           //优化        {            prim[++ok]=i;            for (long long j= i*i; j<=N; j=j+i) // 如果1处用1000必须_int64强制转换            {                f[j]=true;            }        }    }    for (int i=1; i<=ok; i++)    {        biao[prim[i]]=prim[i];        for (long long j= (long long)prim[i]*prim[i]; j<=1e6; j=j+prim[i])        {            if (0==biao[j])                biao[j]=prim[i];        }    }   /* printf("%d\n",prim[ok]);    for (int i=(210)-200;i<=210;i++)        printf("%d ",biao[i]);*/    int n, a, d;    int t;    cin>>t;    while(t--)        // while(scanf("%d", &n)!=EOF)    {        scanf("%d%d",&n,&d);        if (d>1e6)        {            int cun=0;            for (int i=1; i<=ok; i++)            {                if (1LL*prim[i]*d<=n) cun++;                else break;                if (d%prim[i]==0)break;            }            printf("%d\n",cun);        }        else        {            int idx=min(biao[d],(n-1)/d);            int it=upper_bound(prim+1,prim+1+ok,idx)-prim;            printf("%d\n",it-1);        }    }    return 0;}


0 0