zoukankan      html  css  js  c++  java
  • M

    题意:

    求[a,b]之间的素数的个数

    数很大。。。数组开不起

    所以要想到转化

    因为小于等于b的合数的最小质因子 一定小于等于sqrt(b),所以只需要求出来[0,sqrt(b)]的素数  然后取倍数删去[a,b]之间的合数  就好了

    那  为什么小于等于b的合数的最小质因子 一定小于等于sqrt(b)呢?

    因为b是最大的, 所以只讨论b即可 我们来看b的因子 。。一定是从 [0,sqrt(b)] 和 [sqrt(b),b]这两个区间里各取一个

    先来看[0,sqrt(b)] 如果在这里取得是一个合数 则这个合数可由比它小的质数组成  所以只讨论质数即可  然后求倍数。。删除[a,b]之间的合数

    为什么不看 [sqrt(b),b]  因为如果取一个这个区间的数去求倍数删除[a,b]之间的合数的话 ,这个倍数一定是在 [0,sqrt(b)]这个区间的。。。

    所以小于等于b的合数的最小质因子 一定小于等于sqrt(b)

    代码如下:

    #include <iostream>
    #include <cstdio>
    #include <sstream>
    #include <cstring>
    #include <map>
    #include <set>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #define MOD 2018
    #define LL long long
    #define ULL unsigned long long
    #define maxn 100009
    #define Pair pair<int, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define _  ios_base::sync_with_stdio(0),cin.tie(0)
    //freopen("1.txt", "r", stdin);
    using namespace std;
    const int LL_INF = 0x7fffffffffffffff,INF = 0x3f3f3f3f;
    LL primes[maxn];
    bool vis[maxn], bz[maxn];
    int ans = 0;
    void init()
    {
        mem(vis,0);
        vis[1] = 1;
        for(int i=2; i<maxn; i++)
            if(!vis[i])
            {
                primes[ans++] = i;
                for(LL j=(LL)i*i; j<maxn; j+=i)
                    vis[j] = 1;
            }
    }
    
    int main()
    {
        init();
        int T;
        int kase = 0;
        LL a, b;
        cin>> T;
        while(T--)
        {
            int res = 0;
            mem(bz,0);
            cin>> a >> b;
           // if(a <= 2) a = 2;
            int len = b - a;
            for(int i=0; i<ans && primes[i] * primes[i] < b; i++)
            {
                int j = a/primes[i];     
                if(j*primes[i] < a) j++;  // 我们要找到第一个大于等于a的合数,因为出的时候是向下取整  所以要判断一下
                if(j == 1) j++;           // 如果j == 1 则说明 a是一个质数 但我们要找合数 
                while(j * primes[i] <= b)
            { bz[j
    *primes[i] - a] = 1; j++; } } if(a == 1) bz[0] = 1; // a == 1时要特殊讨论 因为1不是一个合数,无法由比它小的质数组成,也不是一个质数,所以在标记bz数组时 没有标记 就会多算 for(int k=0; k<=len; k++) if(!bz[k]) res++; printf("Case %d: %d ",++kase,res); } return 0; }

     

    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    WPF 中 TextBlock 文本换行与行间距
    WPF中TextBox文件拖放问题
    WPF 自定义鼠标光标
    矩形覆盖
    跳台阶和变态跳台阶
    用两个栈实现队列
    重建二叉树
    从尾到头打印链表
    替换空格
    斐波那契数列
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9190660.html
Copyright © 2011-2022 走看看