• codeforces 300E Empire Strikes Back


    题意:给定一个k和k个数字,求最小的数字n使得n!是∑ai!的倍数。

    思路:设cnt[ i ]表示包含素数i出现的数目。把∑ai!的每一个质数的指数求出来,然后二分判断n是否满足条件即可。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #include<queue>
    #include<bitset>
    #include<vector>
    #include<string>
    #include<stack>
    #include<set>
    #define ll long long
    #define PI acos(-1.0)
    #define F first
    #define S second
    #define pb push_back
    #define debug(x); printf("***:%d
    ",x);
    #define des(x); printf("des:%s
    ",x+1);
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int inf=0x3f3f3f3f;
    const ll mod=1e9+7;
    using namespace std;
    const int N=1e6+5;
    const int M=1e7+5;
    ll s;
    ll cao;
    int k;
    ll cnt[M];
    int f[M],prime[M],tot,ans;
    void oula()
    {
        //f[1]=1;
        for (int i=2; i<=1e7; i++)
        {
            if (!f[i])
            {
                prime[++tot]=i; f[i]=i;//欧拉筛筛质数
            }
            for (int j=1; j<=tot; j++)
            {
                if (i*prime[j]>1e7) break;
                f[i*prime[j]]=i;
                if (i%prime[j]==0)
                    break;
            }
        }
    }
    bool check(ll x)
    {
        for(int i=1;i<=tot;i++)
        {
            ll temp=x;
            ll sum=0;
            while(temp)
            {
                temp/=prime[i];//求二分的数包含某一个质数的数目。
                sum+=temp;
            }
            if(sum<cnt[prime[i]])
                return false;
        }
        return true;
    }
    int main()
    {
        oula();
        scanf("%d",&k);
        for(int i=1;i<=k;i++)
        {
            scanf("%lld",&cao);
            s+=cao;
            cnt[cao]++;
        }
        for(ll i=1e7;i>=2;i--)
            cnt[i]+=cnt[i+1];//例:如果是质数29,则29!还要加上31!,30!等里包含的29数目。
        for(ll i=1e7;i>=2;i--)
        {
            cnt[i/f[i]]+=cnt[i];//求大数里包含的小质数数目。
            if(i!=f[i])
                cnt[f[i]]+=cnt[i];
        }
        ll l=1,r=s;
        while(l<=r)
        {
            ll mid=l+r>>1;
            if(check(mid))
            {
                r=mid-1;
            }
            else 
                l=mid+1;
        }
        printf("%lld
    ",l);
        return 0;
    }
  • 相关阅读:
    让思考成为一种习惯:今年,我大四了
    asp.net core源码飘香:Logging组件
    asp.net core源码飘香:Options组件
    asp.net core源码飘香:Configuration组件
    asp.net core源码飘香:从Hosting开始
    webpack code split实现原理
    css specificity
    todo:read
    React Render Props 模式
    recompose mapProps 函数指南
  • 原文地址:https://www.cnblogs.com/switch-waht/p/13679339.html
Copyright © 2020-2023  润新知