zoukankan      html  css  js  c++  java
  • HDU 5317 RGCDQ (数论素筛)

     

    Time Limit: 3000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u

     Status

    Description

    Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more and more interesting things about GCD. Today He comes up with Range Greatest Common Divisor Query (RGCDQ). What’s RGCDQ? Please let me explain it to you gradually. For a positive integer x, F(x) indicates the number of kind of prime factor of x. For example F(2)=1. F(10)=2, because 10=2*5. F(12)=2, because 12=2*2*3, there are two kinds of prime factor. For each query, we will get an interval [L, R], Hdu wants to know max GCD(F(i),F(j)) (Lleq i<jleq R)
     

    Input

    There are multiple queries. In the first line of the input file there is an integer T indicates the number of queries. 
    In the next T lines, each line contains L, R which is mentioned above. 

    All input items are integers. 
    1<= T <= 1000000 
    2<=L < R<=1000000 
     

    Output

    For each query,output the answer in a single line. 
    See the sample for more details. 
     

    Sample Input

    2
    2 3
    3 5
     

    Sample Output

    1
    1
     

    Source

    2015 Multi-University Training Contest 3
    题意:如题,x是一个正整数,f(x)表示x的素因子种类数, F(2)=1. F(10)=2,因为10=2*5. F(12)=2, 因为12=2*2*3。现在给定两个数l和r,问在l和r这个区间内任取两个数i,j中gcd(f(i),f(j))的最大值。给定t组数据,每组给定l和r,输出结果。
    题解:先用素筛法打表筛选出每个数的素因子种类数,我们发现2*3*5*7*11*13*17=510510,注意虽然这个数小于10的6次方,但是已经足够证明7已经是最大值了,因为这7个素数是素数中最小的7个。f(i)只考虑i的素因子种类个数,不考虑这个素因子是否和j的素因子是同一个。举个例子,比如i=2*3*5*7*11*13*17=510510,种类数为7,j=2*3*5*7*11*13*19=570570,种类数也为7,所以如果lr区间中包含ij那么输出7。事实上,510510和570570是最小的两个包含7种素因子的数。说到这里就可以写了,涉及到一点递推的知识,用sum[maxn][8]存储,sum[i][j]表示对于数i来说,2到i中所有数的素因子种类数为j的数的个数。i从7遍历到1,如果sum[r][i]-sum[l-1][i]>=2,说明该区间内存在至少两个数的素因子种类数为i,break输出即可,因为我们要的是最大值。注意初始的时候要把ans定义为1,因为可能所有数的素因子种类数都不相等比如6,7这组数据,f(6)=2,f(7)=1,gcd(2,1)=1。输出1而不是0,虽然输出0也是能AC的但是不符合题意。
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    const int maxn=1e6+5;
    int num[maxn];
    int sum[maxn][8];
    void getnum()
    {
        memset(num,0,sizeof(num));
        memset(sum,0,sizeof(sum));
        for(int i=2;i<maxn;i++)
        {
            if(!num[i])
            {
                for(int j=i;j<maxn;j+=i)
                num[j]++;
            }
        }
        for(int i=2;i<maxn;i++)
        for(int x=1;x<=7;x++)
        {
            sum[i][x]=sum[i-1][x];
            if(num[i]==x)
            sum[i][x]++;
        }
    }
    int main()
    {
        getnum();
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int l,r,ans=1;
            scanf("%d%d",&l,&r);
            for(int i=7;i>=1;i--)
            {
                if(sum[r][i]-sum[l-1][i]>=2)
                {
                    ans=i;
                    break;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Yii2 使用 Beanstalk 队列系统
    Yii2 注册表单验证规则 手机注册时候使用短信验证码
    Yii2 高级模板 多域名管理问题
    PHP生成缩略图,控制图片质量,支持.png .jpg .gif
    yii2-lock-form 也许这就是你想要的,阻止表单多次提交
    PHP日期与时间戳转换
    PHP/Yii2操作Cookie,常见问题以及注意事项
    对称加密,API加密
    yii2弹出层
    两种不同的Context
  • 原文地址:https://www.cnblogs.com/Ritchie/p/5312564.html
Copyright © 2011-2022 走看看