poj 2992 Divisors

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int Prime( int prime[] )
{
int i,j,count=0;
for( int i=2;i<=500;i++ )
{
int j=2,t=i/2;
for( ;j<=t;j++ )
if( i%j==0 )
break;
if( j==( t+1 ) )
{
prime[count++]=i;
}
}
return count;
}
int getp( int n,int p )
{
int SUM=0,t=p;
while( t<=n )
{
SUM+=n/t;
t*=p;
}
return SUM;
}
int main()
{
int prime[500]={0},n,k;
int count=Prime( prime );
while( scanf( "%d%d",&n,&k )!=EOF )
{
int sum[3][300]={0};
memset( sum,0,sizeof( sum ) );
for( int i=0;n>=prime[i];i++ )
sum[0][i]=getp( n,prime[i] );
for( int i=0;n-k>=prime[i];i++ )
sum[1][i]=getp( n-k,prime[i] );
for( int i=0;k>=prime[i];i++ )
sum[2][i]=getp( k,prime[i] );
long long SUM=1;
for( int i=0;i<count;i++ )
SUM *=( sum[0][i]-sum[1][i]-sum[2][i]+1 );
printf( "%lld\n",SUM );
}
// system( "pause" );
}


该题直接用暴力肯定超时,我们可以想到N可以质因数分解,那我们就可以把1~N全部质因数分解;我们知道N=p1^a1*p2^a2……pn^an;则又因子sum=(a1+1)*(a2+1)……(an+1)个;

n!能被p1整除则有n/p1个数能被整除;能被p1^2则有n/p1^2个,同理,能被p1^n则有n/p1^n个;则a1=n/p1+n/p1^2+......n/p1^n;

同理,

n!能被pn整除则有n/pn个数能被整除;能被pn^2则有n/pn^2个,同理,能被pn^n则有n/pn^n个;则a1=n/pn+n/pn^2+......n/pn^n;

posted @ 2011-11-17 17:42  wutaoKeen  阅读(296)  评论(0编辑  收藏  举报