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

    Portal

    重庆的题目质量还是不错的.

    这个刚好为(k)就是一个暗示, 暗示我们枚举超集/子集进行容斥.

    容斥做法:

    咕咕咕


    以下是反演做法.

    (F(n))表示n == k的时候题目所求.

    (G(n))表示k | n 的时候题目所求.

    那么([l, r])范围内有(frac{r}{k} - frac{l - 1}{k})个k的倍数

    那么G(n) = ((frac{r}{k} - frac{l - 1}{k}) ^ N)

    所以F(n) = (sum_{n | d} mu(frac{d}{n}) * (frac{H}{d} - frac{L - 1}{d}) ^ N)

    [= sum_{s} mu(s) (frac{H}{sk} - frac{L - 1}{sk}) ^ N ​ ]

    然后直接杜教筛就可以了

    其实Mu反演也是一种容斥

    Upd 20190109:

    关于这类反演, 有几个可以注意的地方, 帮我们发现如何进行反演:

    关于枚举子集/超集: 简单来说哦就是如何好算如何算.

    发现这题是一个区间内的问题,一个区间内的倍数的数量可直接由除法原理求得.

    如果要是枚举约数, 考虑这个式子:

    [sum_{i = 1}^{n} sigma_0(n) = sum_{i} lfloor frac{n}{i} floor ]

    如果i从1开始, 还是可以考虑枚举因数的.

    #include<bits/stdc++.h>
    #include<ext/pb_ds/assoc_container.hpp>
    #include<ext/pb_ds/hash_policy.hpp>
    using namespace std;
    #define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
    #define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
    #define clar(a, b) memset((a), (b), sizeof(a))
    #define debug(...) fprintf(stderr, __VA_ARGS__)
    typedef long long LL;
    typedef long double LD;
    int read() {
        char ch = getchar();
        int x = 0, flag = 1;
        for (;!isdigit(ch); ch = getchar()) if (ch == '-') flag *= -1;
        for (;isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
        return x * flag;
    }
    void write(int x) {
        if (x < 0) putchar('-'), x = -x;
        if (x >= 10) write(x / 10);
        putchar(x % 10 + 48);
    }
    
    const int MaxDta = 1e5 + 9, Threshold = 1e6 + 9, Mod = 1e9 + 7;
    static int prime[Threshold], tot, mu[Threshold], pSumMu[Threshold];
    static bool isnprime[Threshold];
    __gnu_pbds :: gp_hash_table <int, int> prefixMu;
    
    int fpm(int base, int tims) { 
    	int r = 1;
    	while (tims) {
    		if (tims & 1) r = 1ll * r * base % Mod;
    		base = 1ll * base * base % Mod;
    		tims >>= 1;
    	}
    	return r;
    }
    
    void linearSieve() {
    	mu[1] = 1;
    	rep (i, 2, Threshold - 1) {
    		if (!isnprime[i]) prime[++tot] = i, mu[i] = -1;
    		for (int k, j = 1; j <= tot && (k = i * prime[j]) < Threshold; ++j) {
    			isnprime[k] = 1;
    			if (i % prime[j] == 0) {
    				mu[k] = 0;
    				break;
    			} else mu[k] = -mu[i];
    		}
    	}
    
    	rep (i, 1, Threshold - 1) pSumMu[i] = pSumMu[i - 1] + mu[i];
    }
    
    int muSum(int Bound) {
    	if (Bound < Threshold) return pSumMu[Bound];
    	if (prefixMu[Bound]) return prefixMu[Bound];
    
    	int Sum = 1;
    	for (int l = 2, r; l <= Bound; l = r + 1) {
    		r = Bound / (Bound / l);
    		Sum -= (r - l + 1ll) * muSum(Bound / l);
    	}
    
    	return prefixMu[Bound] = Sum;
    }
    
    static int N, K, L, H;
    
    void init() {
    	linearSieve();
    	N = read(), K = read(), L = read() - 1, H = read();
    	H /= K; L /= K;
    }
    
    void solve() {
    	LL ans = 0;
    
    	for (int l = 1, r; l <= H; l = r + 1) {
    		if (L / l == 0) r = H / (H / l); else r = min(H / (H / l), L / (L / l));
    		(ans += 1ll * (muSum(r) - muSum(l - 1) + Mod) % Mod * fpm(H / l - L / l, N) % Mod) %= Mod;
    	}
    
    	cout << ans << endl;
    }
    
    int main() {
    //	freopen("LG3172.in", "r", stdin);
    //	freopen("LG3172.out", "w", stdout);
    
    	init();
    	solve();
    
    #ifdef Qrsikno
        debug("
    Running time: %.3lf(s)
    ", clock() * 1.0 / CLOCKS_PER_SEC);
    #endif
        return 0;
    }
    
    
  • 相关阅读:
    backup-rsync主机配置
    msyqldump备份
    会话固定攻击(session fixation attack)
    正确理解 Session 的安全性
    Yii自定义辅助函数
    php缓冲机制及嵌套级别 ob_get_level
    method_exists 与 is_called
    给类动态添加新方法
    PHP Closure(闭包)类详解
    PHP Closure(闭包)类详解
  • 原文地址:https://www.cnblogs.com/qrsikno/p/10246900.html
Copyright © 2011-2022 走看看