• poj2992 Divisors


    考虑对n!进行快速质数分解,对任意质数p,有质数p在n!中出现次数

    cnt(n,p)= n / p + n / p / p +...(*)

    正确性也很容易说明,由于n! = 1 * 2 *...*n, 我们只需考虑不超过n的数m对p的出现次数的贡献次数cnt(m):

    m= p^k * m1,其中m1与p互质,cnt(m) = k。

    那么(*)式右边第一项表示从n个数中取出含有质因子p的数的个数,

    此时显然所有含有质因子p的数对等式左边贡献1,

    取出的数分别为p*1, p*2,...,p*(n /p)

    用p除取出的数,反复以上过程,可实得到n!中质因子p出现次数的值。

    http://poj.org/problem?id=2992

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 typedef __int64 LL;
     5 using namespace std;
     6 const int maxn = 450;
     7 int prime[maxn], k;
     8 int cnt[maxn][maxn];
     9 //cnt[i][j] :: prime[j]^cnt[i][j] | i!
    10 bool vis[maxn];
    11 int n, m;
    12 
    13 void init(){
    14     k = 0;
    15     memset(vis, 0, sizeof vis);
    16     for(int i = 2; i < maxn; i++) if(!vis[i]){
    17         prime[k++] = i;
    18         for(int j = i; j < maxn; j += i) vis[j] = 1;
    19     }
    20     memset(cnt, 0, sizeof cnt);
    21     for(int i = 1; i < maxn; i++){
    22         for(int j = 0; j < k; j++){
    23             int cnt1 = 0, p = i;
    24             while(p / prime[j]) cnt1 += p / prime[j], p /= prime[j];
    25             cnt[i][++cnt[i][0]] = cnt1;
    26         }
    27     }
    28 }
    29 
    30 void solve(){
    31     LL ans = 1;
    32     for(int i = 1; i <= k; i++) ans *= (cnt[n][i] - cnt[m][i] - cnt[n - m][i] + 1);
    33     printf("%I64d
    ", ans);
    34 }
    35 
    36 int main(){
    37     //freopen("in.txt", "r", stdin);
    38     init();
    39     while(~scanf("%d%d", &n, &m)) solve();
    40     return 0;
    41 }
    View Code
  • 相关阅读:
    View Controller 生命周期的各个方法的用法
    IOS开发之Post 方式获取服务器数据
    委托代理
    Function
    SKPhysicsContactDelegate协议
    UITouch附加
    Remove Duplicates from Sorted Array II
    4Sum
    [Text Justification
    Count and Say
  • 原文地址:https://www.cnblogs.com/astoninfer/p/4811554.html
Copyright © 2020-2023  润新知