您的位置:首页 > 其它

fzu-1753 Another Easy Problem-快速求N!中有多少个p

2014-08-09 19:39 351 查看
就是算出来每一个C(N,M)是由哪些数乘来的就好。。。。

#include <iostream>

#include<stdio.h>

#include<vector>

#include<queue>

#include<stack>

#include<string.h>

#include<algorithm>

#include<math.h>

using namespace std;

#define LL long long

#define lcm(a,b) (a*b/gcd(a,b))

//O(n)求素数,1-n的欧拉数

#define N 110000

#define PM 11000

struct math_use

{

int phi
;

vector<int>prime;

void mkphilist()

{

int i,j;

phi[1]=1;

for(i=2; i<N; ++i)

if(!phi[i])

for(j=i; j<N; j+=i)

{

if(!phi[j])

phi[j]=j;

phi[j]-=phi[j]/i;

}

prime.clear();

for(int i=2; i<N; i++)

{

if(phi[i]==i-1)prime.push_back(i);

}

}

//N!中素因子P的个数

//复杂度p^x约等于n!,复杂度为x

LL nump(LL n,LL p)

{

LL cnt=0;

while (n)

{

cnt+=n/p;

n/=p;

}

return cnt;

}

} M;

int num[PM];

LL mul(LL a,LL b)

{

LL ret=1;

LL tmp=a;

while(b)

{

//基数存在

if(b&0x1) ret=ret*tmp;

tmp=tmp*tmp;

b>>=1;

}

return ret;

}

int pp;

void dos(LL n,LL m)

{

int len=M.prime.size();

int x=0;

int ks=-1;

for(int i=0; i<=pp; i++)

{

x=M.nump(n,M.prime[i])-M.nump(m,M.prime[i])-M.nump(n-m,M.prime[i]);

num[i]=min(num[i],x);

if(x!=0)ks=max(ks,i);

}

pp=min(pp,ks);

}

int main()

{

LL n,m;

int t;

M.mkphilist();

while(~scanf("%d",&t))

{

for(int i=0; i<PM; i++)num[i]=99999999;

pp=M.prime.size()-1;

for(int i=1; i<=t; i++)

{

scanf("%I64d%I64d",&n,&m);

dos(n,m);

}

int len=M.prime.size();

LL ans=1;

for(int i=0; i<=pp; i++)

{

ans=ans*mul(M.prime[i],num[i]);

}

cout<<ans<<endl;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: