• Codeforces 385C 线性筛素数


    题意:给定一个数组,求[l,r] 区间,区间里的素数,数组中,能被这个素数整除的个数,再求和。

    分析:区间很大,10^9了,找去区间内的素数是不可能的,但是,数组的数很小,而且要能整除区间内的素数,所以,这些很大的素数是没用的,筛出10^7以内的素数就ok了。

    怎么算个数呢?

    质因数分解,hash一下,再二分区间,应该是很麻烦了,但是网上还有麻烦的,还用到了线段树维护。

    简单方式是:

    将数组hash,在筛素数的时候,检测hash值,是否有这些数,有的话,记录到这个素数中,也就是说,这个数组中,能被这个素数整除的有s个,然后对s求一个前缀和,问题就转换为一个区间和。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    //10^7以内的素数
    const int maxn = 10000000+5;
    
    int vis[maxn],g[maxn],s[maxn];
    
    int m;
    int main(int argc, char const *argv[])
    {
        memset(vis,0,sizeof(vis));
        memset(g,0,sizeof(g));
        memset(vis,0,sizeof(vis));
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++) {
            int x;
            scanf("%d",&x);
            g[x]++;
        }
    
        for(int i=2;i<maxn;i++) {
            if(vis[i]) continue;
            for(int j=i;j<maxn;j+=i) {
                if(g[j])
                    s[i] +=g[j];
                vis[j] = 1;
            }
        }
    
        for(int i=1;i<maxn;i++)
            s[i] +=s[i-1];
    
        int a,b;
        scanf("%d",&m);
        for(int i=0;i<m;i++) {
            scanf("%d%d",&a,&b);
            if(a>=maxn) a = maxn-1;
            if(b>=maxn) b = maxn-1;
            printf("%d
    ",s[b]-s[a-1]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    UI Automator Viewer工具的使用
    SQL数据库面试50题(转载)
    Python +selenium+pycharm(Windows)
    python安装及环境变量配置(Windows)
    JDK的安装与环境变量配置
    shell参数
    文件添加行号
    CentOS 7修改UTC为CST
    shell控制超时
    fio笔记
  • 原文地址:https://www.cnblogs.com/TreeDream/p/7256779.html
Copyright © 2020-2023  润新知