zoukankan      html  css  js  c++  java
  • poj2992

    题意:给n,k,求c(n,k)的约束个数。

    分析:用组合数学的方法求因子个数,我们分别对n!,(n-k)!,k!分解质因数。c(n,k)=n!/((n-k)!k!),把对应因子个数相减,我们就得到了c(n,k)分解的结果。把取每个质因子的方法数相乘即为所求。所以我们需要一种快速分解x!的方法。我们可以枚举所有x!中存在的素因子,对于每个素因子求个数的方式来分解。而对于一个素因子p,我们求在x!中的方法如下,1~x中有x/p个数可以被p整除,所以x!中至少有x/p个p。然后我们再看有多少个p^2。能被p^2整除的数一定能被p整除。所以我们先将1~x中不能被p整除的数刨除。再将剩下的数除以p。现在还能被p整除的数,原来一定包含p^2。而现在剩下的数是1~x/p,问题被我们转化为了一个子问题。(x/p)!中包含多少p。这样递归求解即可。

    View Code
    #include <iostream>
    #include
    <cstdlib>
    #include
    <cstring>
    #include
    <cstdio>
    #include
    <cmath>
    using namespace std;

    #define maxn 505

    int n, k;
    bool is[maxn];
    int pos[maxn];
    int prm[maxn];
    int f[maxn], g[maxn];

    int getprm(int n)
    {
    int i, j, k = 0;
    int s, e = (int) (sqrt(0.0 + n) + 1);
    memset(
    is, 1, sizeof(is));
    prm[k
    ++] = 2;
    is[0] = is[1] = 0;
    for (i = 4; i < n; i += 2)
    is[i] = 0;
    for (i = 3; i < e; i += 2)
    if (is[i])
    {
    pos[i]
    = k;
    prm[k
    ++] = i;
    for (s = i * 2, j = i * i; j < n; j += s)
    is[j] = 0;
    }
    for (; i < n; i += 2)
    if (is[i])
    {
    pos[i]
    = k;
    prm[k
    ++] = i;
    }
    return k;
    }

    int cal(int n, int &p)
    {
    if (n < p)
    return 0;
    return n / p + cal(n / p, p);
    }

    int main()
    {
    //freopen("t.txt", "r", stdin);
    int t = getprm(500);
    while (scanf("%d%d", &n, &k) != EOF)
    {
    long long ans = 1;
    for (int i = 0; i < t && prm[i] <= n; i++)
    ans
    *= cal(n, prm[i]) - cal(n - k, prm[i]) - cal(k, prm[i]) + 1;
    printf(
    "%lld\n", ans);
    }
    return 0;
    }
  • 相关阅读:
    (二)微信开发工具
    (一)微信小程序环境搭建
    mysql安装--window版
    (六--二)scrapy框架之持久化操作
    windows安装redis
    (六--一)scrapy框架简介和基础应用
    (五)selenuim和phantonJs处理网页动态加载数据的爬取
    (四)requests模块的cookies和代理操作
    (三)三种数据解析方式学习
    (二)requests模块
  • 原文地址:https://www.cnblogs.com/rainydays/p/2177066.html
Copyright © 2011-2022 走看看