zoukankan      html  css  js  c++  java
  • Luogu 3172 [CQOI2015]选数

    考虑枚举$k$的倍数$dk$,容易知道$left lceil frac{L}{K} ight ceilleq dleq left lfloor frac{H}{k} ight floor$

    我们设全部$n$个数含有公因子$dk$且全部数互不相同的方案数是$f(d)$,记$x = (left lceil frac{L}{K} ight ceil - left lfloor frac{H}{k} ight floor + 1)$

        那么$f(d) = (x^{n} - x)$

    但是这样不是完全对的,因为这样子相当于把最大公因数是$2k,3k...$的情况也考虑进去了,我们最后还要容斥掉$f(2) f(3)...$这些数

    其实就是一个莫比乌斯函数啦……线性筛一波

    答案$ans = sum_{i = 1}^{x - 1}f_{i} * mu _{i}$

    最后注意当$left lceil frac{L}{K} ight ceil$为$1$的时候,全部都选1也是一种可行的方案。

    时间复杂度$O(nlogn)$

    Code:

    #include <cstdio>
    using namespace std;
    typedef long long ll;
    
    const int N = 1e5 + 5;
    const ll P = 1e9 + 7;
    
    int n, ln, rn, k, pCnt = 0, pri[N];
    ll mu[N], f[N];
    bool np[N];
    
    inline ll pow(ll x, ll y) {
        ll res = 1;
        for(; y > 0; y >>= 1) {
            if(y & 1) res = res * x % P;
            x = x * x % P;
        }
        return res;
    }
    
    inline void sieve() {
        mu[1] = 1LL;
        for(int i = 2; i <= rn - ln; i++) {
            if(!np[i]) {
                mu[i] = -1LL;
                pri[++pCnt] = i;
            }
            for(int j = 1; j <= pCnt && pri[j] * i <= rn - ln; j++) {
                np[i * pri[j]] = 1;
                if(i % pri[j] == 0) break;
                else mu[i * pri[j]] = -mu[i];
            }
        } 
    }
    
    int main() {
        scanf("%d%d%d%d", &n, &k, &ln, &rn);
        
    /*    if(ln % k) ln = ln / k + 1; 
        else ln /= k; */
        ln = (ln + k - 1) / k, rn /= k;
        if(ln > rn) return puts("0"), 0;
        
        sieve();
        
        for(int i = 1; i <= rn - ln; i++) {
            int l = ln, r = rn;
    /*        if(l % i) l = l / i + 1; 
            else l /= i;  */
            l = (l + i - 1) / i, r /= i;
            if(l > r) continue;
            f[i] = (pow(r - l + 1, n) - (r - l + 1) + P) % P;
        }
        
        ll ans = 0;
        for(int i = 1; i <= rn - ln; i++)
            ans = (ans + f[i] * mu[i] % P + P) % P;        
        if(ln == 1) ans = (ans + 1LL) % P;
        printf("%lld
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    C# WinForms多线程编程-摇奖程序
    C#多线程编程实例介绍
    C#多线程编程(1) —— 多线程与UI操作
    C#引用类型与值类型浅析
    HTML中空格占位符的几种方式
    C#中字符串排序的问题和解决方法
    InstanceContextMode和ConcurrencyMode的默认值
    The "IsFileSystemCaseSensitive" parameter is not supported by the "FindConfigFiles" task
    jQuery中delegate() 和 on()的出现版本
    NHibernate 分页优化,针对SQLServer(未深入测试)
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9481710.html
Copyright © 2011-2022 走看看