• codeforces 83 D. Numbers


    题意:

    给出l,r,k,(1 ≤ l ≤ r ≤ 2·109, 2 ≤ k ≤ 2·109)

    求在区间[l,r]内有多少个数i满足 k | i,且[2,k-1]的所有数都不可以被i整除

    首先,如果k不是素数的话,答案肯定是0

    考虑k是素数:

    fir[i]保存i的第一个素因子,fir[]可以在线性筛的时候得到

    我们先把N以内的数线性筛出来

    所以其实就是求:

    [l,r]中满足fir[i] = k 的i的个数

    [l,r] = [1,r] - [1,l-1]

    所以现在我们要求的就是:

    [1,r]中满足fir[i] = k 的i的个数,也就是

    [1,r/k]中满足fir[i] >= k 或 i = 1的i的个数

    n = r / k

    如果n <N,直接遍历fir,统计fir[i] >= k || i == 1 的i的个数

    如果n >= N,就相当于要把[1,n]中2的倍数,3的倍数,等小于k的素数的倍数筛去

    dfs搜,容斥,考虑到2 * 3 * ... * 23 * 29 > 2 * 10^9,所以复杂度不会很大

    这个套路也很喜闻乐见

    代码:

                                                
      //File Name: cf83D.cpp
      //Created Time: 2017年01月04日 星期三 22时48分56秒
                                       
    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int MAXN = 30000000 + 1;
    bool check[MAXN];
    int prime[2000000],fir[MAXN],tot;
    LL ans,n;
    int ma;
    void init(){
        tot = 0;
        memset(check,false,sizeof(check));
        for(int i=2;i<MAXN;++i){
            if(!check[i]){
                prime[tot++] = i;
                fir[i] = i;
            }
            for(int j=0;j<tot;++j){
                if((LL)i * prime[j] >= MAXN) break;
                check[i * prime[j]] = true;
                fir[i * prime[j]] = prime[j];
                if(i % prime[j] == 0) break;
            }
        }
    //    printf("tot = %d
    ",tot);
    }
    bool is_prime(LL k){
        if(k < MAXN)
            return fir[k] == k;
        for(int i=0;i<tot;++i){
            if(1LL * prime[i] * prime[i] > k) break;
            if(k % prime[i] == 0) return false;
        }
        return true;
    }
    void dfs(int p,LL now,LL f){
        if(now > n) return ;
        if(p > ma){
            ans += f * (n / now);
            return ;
        }
        dfs(p+1,now,f);
        dfs(p+1,now * prime[p],-f);
    }
    LL cal(LL r,LL k){
        ans = 0;
        n = r / k;
        if(n < MAXN){
            for(int i=1;i<=n;++i){
                if(i == 1 || fir[i] >= k) 
                    ++ans;
            }
            return ans;
        }
        else{
            ma = 0;
            for(;ma<tot;++ma){
                if(prime[ma] == k)
                    break;
            }
            --ma;
            dfs(0,1,1);
            return ans;
        }
    }
    LL solve(LL l,LL r,LL k){
        if(!is_prime(k)) return 0;
        return cal(r,k) - cal(l - 1,k);
    }
    int main(){
        init();
    //    while(cin >> n){
    //        cout << fir[n] << endl;
    //    }
        LL l,r,k;
        cin >> l >> r >> k;
        cout << solve(l,r,k) << endl;
        return 0;
    }
  • 相关阅读:
    Microsoft .NET Framework 远程执行代码漏洞
    GE PACSystems RX3i 输入验证漏洞
    Windows10 1809版本Windows自动更新服务无法禁用问题解决方案
    企业网络防范Serv-U的漏洞
    jsp安全问题及其解决建议
    Windows XP系统搜索故障及处理办法点点通
    开启路由器的TCP拦截
    从MyIE2平滑升级到Maxthon的完美方案
    全面解析UNIX缓冲区溢出 深度防御体系
    从异常系统进程检查企业网络安全 (二)
  • 原文地址:https://www.cnblogs.com/-maybe/p/6250771.html
Copyright © 2020-2023  润新知