• 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;
    }






























































    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    晓歌:全球金融危机十周年,下一场金融危机不可避免且更惨烈?
    要让孩字喜欢上错误,但不是喜欢出错
    RSA 加密原理
    《道德经》里的“道”和“德”到底是什么意思?
    利用大数据做好消费者运营,你该了解这些
    世界上最著名的操作系统是用什么语言编写的?
    一篇文章带你快速弄清楚什么是终端
    一篇文章看清楚 Linux 的职业发展方向
    微软:悬赏10万美金破解 Linux 系统
    2020年你最需要掌握的11种编程语言
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4650581.html
Copyright © 2020-2023  润新知