码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 439E Devu and Birthday Celebration(计数问题)

时间:2014-06-28 07:02:46      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:style   http   color   get   width   os   

题目链接:Codeforces 439E Devu and Birthday Celebration

题目大意:给出q,表示询问的次数,每次询问有n和f,问有多少种分类方法,将n分成f份,并且这f份的最大共约数为1.

解题思路:如果不考虑说最大共约数为1的话,那么问题很简单,就是f个数的和为n的种数C(f?1n?1).所以我们就尽量将问题转化成说f数的和为s的子问题。用容斥原理,总的可能减去公约数不为1的情况,那么公约数不为1的情况就去枚举公约数。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 1e5+5;
const int MOD = 1e9+7;

vector<int> vec;
int fact[N], ive_fact[N];

int power (int x, int n) {
    int ans = 1;

    while (n) {
        if (n&1)
            ans = (1ll * ans * x) % MOD;

        n /= 2;
        x = (1ll * x * x) % MOD;
    }
    return ans;
}

void init () {
    fact[0] = 1;
    for (int i = 1; i < N; i++)
        fact[i] = (1ll * fact[i-1] * i) % MOD;

    for (int i = 0; i < N; i++)
        ive_fact[i] = power(fact[i], MOD-2);
}

void divFactor(int cur) {  

    vec.clear();
    int tmp = sqrt(cur+0.5);  
    for (int i = 2; i <= tmp; i++) {  
        if (cur % i == 0) {
            vec.push_back(i);
            while (cur % i == 0)
                cur /= i;  
        }
    }  

    if (cur != 1)
        vec.push_back(cur);
} 

int solve (int n,int f) {
    if (n < f)
        return 0;
    int ans = fact[n];
    ans = 1ll * ans * ive_fact[f] % MOD;
    ans = 1ll * ans * ive_fact[n-f] % MOD;
    return ans;
}

int cal (int n) {
    return (n % MOD + MOD) % MOD;
}

int main () {
    init();
    int cas;
    scanf("%d", &cas);

    while (cas--) {
        int n, f;
        scanf("%d%d", &n, &f);
        divFactor(n);

        int ans = 0, t = 1<<vec.size();
        for (int i = 0; i < t; i++) {
            int tmp = 1, sign = 1;
            for (int j = 0; j < vec.size(); j++) {
                if (i&(1<<j)) {
                    sign *= -1;
                    tmp *= vec[j];
                }
            }

            ans = cal(ans + sign * solve(n/tmp - 1, f - 1));
        }
        printf("%d\n", ans);
    }
    return 0;
}

Codeforces 439E Devu and Birthday Celebration(计数问题),布布扣,bubuko.com

Codeforces 439E Devu and Birthday Celebration(计数问题)

标签:style   http   color   get   width   os   

原文地址:http://blog.csdn.net/keshuai19940722/article/details/35293943

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!