首页 > 代码库 > fzu-1753 Another Easy Problem-快速求N!中有多少个p

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

就是算出来每一个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[N];
    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;
}