zoukankan      html  css  js  c++  java
  • Codeforces 493 E.Devu and Birthday Celebration

    ## [$>Codeforces space 493 E.Devu and Birthday Celebration<$](http://codeforces.com/problemset/problem/493/E)

    题目大意 : 有 (q) 组询问,每次有 (n) 小朋友和 (m) 个苹果,求有多少种方案,使得每个小朋友都分到一个苹果,且每个小朋友分到的苹果的数目的 (gcd = 1),输出答案对 (10^9 + 7) 取模的值

    (1 leq n, m, q leq 10^5)

    解题思路 :

    (f(n)) 表示分苹果的方案满足 (n | gcd) 的方案数,(g(n)) 表示分苹果的方案满足 (gcd = n) 的方案数

    显然有 (f(n) = sum_{n|d} g(d))

    考虑到 (f(n)) 本质上是将 (frac{M}{n}) 个球,放到 (N) 个不同盒子里盒子不能为空的方案数,插板法组合数求解即可

    通过简单的莫比乌斯反演可以得到 (g(n) = sum_{n|d} mu(frac{n}{d}) f(d))

    实际上对于每一组询问我们要求的就是 (g(1)) 的值,而对于 (f(n)) 来说,只有当 (n|M) 的时候才可能有值

    所以只需要大力枚举 (M) 的因子,预处理组合数和莫比乌斯函数 (O(1)) 计算单个 (f) 的值即可

    总复杂度是 (O(Qsqrt{m}))


    /*program by mangoyang*/
    #include<bits/stdc++.h>
    #define inf (0x7f7f7f7f)
    #define Max(a, b) ((a) > (b) ? (a) : (b))
    #define Min(a, b) ((a) < (b) ? (a) : (b))
    typedef long long ll;
    using namespace std;
    template <class T>
    inline void read(T &x){
        int f = 0, ch = 0; x = 0;
        for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
        for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
        if(f) x = -x;
    }
    #define int ll
    
    const int N = 200005, Mod = 1000000007;
    int js[N], mu[N], b[N], prime[N], inv[N], tot, n, m;
    
    inline int Pow(int a, int b){
        int ans = 1;
        for(; b; b >>= 1, a = a * a % Mod) 
            if(b & 1) ans = ans * a % Mod; 
        return ans;
    }
    inline void Prework(){
        mu[1] = 1, js[0] = 1, inv[0] = 1;
        for(int i = 1; i < N; i++) 
            js[i] = js[i-1] * i % Mod, inv[i] = Pow(js[i], Mod - 2);
        for(int i = 2; i < N; i++){
            if(!b[i]) prime[++tot] = i, mu[i] = -1;
            for(int j = 1; j <= tot && i * prime[j] < N; j++){
                b[i*prime[j]] = 1;
                if(i % prime[j]) mu[i*prime[j]] = -mu[i]; else break; 
            } 
        }
    }
    
    inline int C(int n, int i){ return js[n] * inv[i] % Mod * inv[n-i] % Mod; }
    inline int calc(int x){ return x < m ? 0 : C(x - 1, m - 1) * mu[n/x] % Mod; }
    
    inline void solve(){
        int ans = 0; read(n), read(m);
        int num = (int) sqrt(n);
        for(int i = 1; i <= num; i++) if(n % i == 0){
            int x = i, y = n / i;
            (ans += calc(x)) %= Mod;
            if(x != y) (ans += calc(y)) %= Mod; 
        }
        printf("%lld
    ", ((ans % Mod) + Mod) % Mod);
    }
    
    signed main(){
        Prework();
        int T; read(T); while(T--) solve();
        return 0;
    }
    
  • 相关阅读:
    linux下shell显示-bash-4.1#不显示路径解决方法
    update chnroute
    An error "Host key verification failed" when you connect to other computer by OSX SSH
    使用dig查询dns解析
    DNS被污染后
    TunnelBroker for EdgeRouter 后记
    mdadm详细使用手册
    关于尼康黄的原因
    Panda3d code in github
    Python实例浅谈之三Python与C/C++相互调用
  • 原文地址:https://www.cnblogs.com/mangoyang/p/9445720.html
Copyright © 2011-2022 走看看