poj:2992 因子数量

题意:

求 组合数c(n,k)的因子数量

由算术基本定理很容易求得,不过第一次却T了,加了好多预处理,o1查询,才过

#include <iostream>
#include <stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<ctype.h>
using namespace std;
#define I64d lld
int prime[100];
int isnotprime[500];
int fac[500][100];
int nfac[500][100];
long long ans[500][500];
int np;
void setprime()
{
    np=0;
    for(int i=2;i<=431;i++)
    {
        if(!isnotprime[i])
        {
            prime[np++]=i;
        }
        for(int j=0;j<np&&i*prime[j]<=431;j++)
        {
            isnotprime[i*prime[j]]=1;
            if(i%prime[j]==0)
                break;
        }
    }
    return;
}
void setfac()
{
    memset(fac,0,sizeof(fac));
    for(int i=2;i<=431;i++)
    {
        int p=i;
        for(int j=0;j<np;j++)
        {
            while(p%prime[j]==0)
            {
                fac[i][j]++;
                p/=prime[j];
            }
        }
    }
    return;
}
void setans()
{
    memset(nfac,0,sizeof(nfac));
    for(int i=2;i<=431;i++)
    {
        for(int j=0;j<np;j++)
            nfac[i][j]=nfac[i-1][j]+fac[i][j];
    }
    for(int n=0;n<=431;n++)
    {
        for(int k=0;2*k<=n;k++)
        {
            long long res=1;
            for(int i=0;i<np;i++)
            {
                res*=nfac[n][i]-nfac[k][i]-nfac[n-k][i]+1;
            }
            ans[n][k]=ans[n][n-k]=res;
        }
    }
    return;
}
int main()
{
    setprime();
    setfac();
    setans();
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        printf("%I64d\n",ans[n][k]);
    }
    return 0;
}
时间: 2024-10-09 22:58:42

poj:2992 因子数量的相关文章

POJ 2992 Divisors 求组合数因子个数

题目来源:POJ 2992 Divisors 题意:... 思路:素数分解的唯一性 一个数可以被分解成若干素数相乘 p1^x1*p2^x2*...*pn^xn 根据乘法原理 因子数为 (x1+1)*(x2+1)*...*(xn+1) 不能直接求出组合数 会溢出 也不能把每个乘的数分解因子 这样会超时 C(N,M)=N!/(M!*(N-M)!) 另dp[i][j] 代表为i的阶乘中j因子的个数(j是素数) 那么i素数的个数为dp[n][i]-dp[m][i]-dp[n-m][i] 最后for循环从

poj 2992 Divisors 整数分解

设m=C(n,k)=n!/((n-k)!*k!) 问题:求m的因数的个数 将m分解质因数得到 p1有a1个 p2有a2个 .... 由于每个质因数可以取0~ai个(全部取0就是1,全部取ai就是m)最后的答案就是(a1+1)*(a2+1)*....* 注意不能直接将m分解,因为太大,所以要先分解n,n-k,k,根据他们再来加减. #include <iostream> #include <cstdio> #include <cmath> #include<cstr

POJ 2992 求组合数的因子个数

求C(n,k)的因子个数 C(n,k) = (n*(n-1)*...*(n-k+1))/(1*2*...*k) = p1^k1 * p2^k2 * ... * pt^kt 这里只要计算出分子中素数因子个数减去分母中的个数 然后每一种因子都有 (cnt+1)种取的可能,乘一下就出来了 但是不能逐个因子分解,试了两次都错了,后来初始的时候,先将这432个数提前预处理分解好保存到vector中 然后用的时候直接提取就行 不然会因为数据量太大超时的 1 #include <iostream> 2 #i

poj 2992 Divisors

题目链接:http://poj.org/problem?id=2992 题目大意:就是叫你求组合数C(n,m)的因子的个数. 思路:求解这题需要用到以下几个定理 1.对任意的n,可以这么表示 n=p1^e1*p2^e2*p3*e3*......pn^en .(p1,p2,p3......pn都为素数) 2.对任意的n的因子数为:(1+e1)*(1+e2)*(1+e3)*......*(1+en) 3.n!的素数因子=(n-1)!的素数因子+n的素数因子 4.C(n,k)的素因子=n!的素因子 -

将一个整数数组先按照因子数量排序,再按照数字大小排序,输出第k个数

同小米OJ比赛题:现在有 n 个数,需要用因子个数的多少进行排序,因子个数多的排在后面,因子个数少的排在前面,如果因子个数相同那么就比较这个数的大小,数大的放在后面,数小的放在前面.现在让你说出排序之后第 KK 个位置的数字是多少. 原文地址:https://www.cnblogs.com/graybird/p/10797991.html

POJ 2992

此题A得艰难,应该是有很多组数据吧,使得容易超时. 直接求出组合数是不可能的,因而,只能把各个数都计算其各素因子个数,再计算即可. 而直接计算,必定是要超时的,所以,只好先预处理所有结果,再输出了. 首先筛选素数,分解0~440的素因子. 然后,Cnk=(n*(n-1)*(n-2)*...(n-k+1))/k!,计算,按各数所拆解素因子计算出组合数的素因子及其个数,再求出即可. 而对于Cn(k+1)=(n*(n-1)*(n-2)*...(n-k+1)*(n-k))/(k+1)!只需在Cnk的基础

组合数学+整数分解 POJ 2992 Divisors

题意:给n,k,求C(n,k)的约数的个数. 由于C(n,k)=n!/(k!*(n-k)!),所以只要分别把分子分母的素因子的次数求出来,再用分子的每个素因子的次数减去分母的每个素因子的次数就可以得到C(n,k)的素数分解式,约数个数就等于(p1+1)(p2+1)*...*(pn+1).这道题n,k的范围都是四百多,按理说O(N^2)的算法可以过的,但是测试数据太多了,暴力的方法会TLE.看别人的报告知道了求N!的某个素因子次数的递归算法,然后枚举每个素数,求出它在阶乘中的次数,就可以AC了.

poj 3735 大数量重复操作问题(矩阵快速幂)

题意:一个一维数组,3种操作: a:  第i个数+1,b: 第i个数=0 ,c::交换某俩处的数.  由三种基本操作构成一组序列,重复该序列m次(m<10^9),问结果 属于一种综合操作重复型: 每次乘以一矩阵T,相当于做一次操作.关键是构造这个矩阵. 先构造最初矩阵A :  1*(n +1) ={1,0,0,0...} ,  第一个一时为了操作第一行数的, T的构造:初始是N+1 * N+1单位阵 这样恰好操作第i个数, +1,就在第0行的第 i个加1:交换就对应列交换,清零就对应列清0. a

POJ 2992-Divisors(求组合数质因子的个数)

Divisors Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2992 Appoint description:  System Crawler  (2015-04-24) Description Your task in this problem is to determine the number of divisors of C