zoukankan      html  css  js  c++  java
  • Topcoder SRM 661 (Div.1) 250 MissingLCM

    【题意】

    给你一个数N(1<=N<=10^6),要求最小的M(M>N),使得lcm(n+1,n+2,...m)=lcm(1,2,3,...,m)

    【思路】 

    手速太慢啦,等敲完代码的时候发现比赛已经结束了

    一开始我想直接枚举m,并判断lcm(1,..,m)与lcm(n+1,n+2,...,m)是否相等,但发现,当求到lcm(1,...,40)的时候就爆LL了

    显然不能这样求

    也就是说,要求出具体lcm(1,2,...,m)的值是很困难的

    怎么求

    可以把它分解质因数,分解成几个质数相乘的形式

    判断lcm(1,...,m)和lcm(n+1,n+2,...,m)的质因数是否完全一样。

    但是仅仅1~1000000的质数有8万个

    枚举m再枚举质数显然吃不消。

    然而我注意到有一条性质(不知道算不算)

    假设有质数K,可以求出t,使得K的t次方刚好小于m(K^t<=m)

    那么lcm(1,2,...,m)分解质因数中一定而且最多有t个质数K连乘,

    这样就可以很快地吧lcm(1,2,...,m)分解质因数

    那么怎么把lcm(n+1,n+2,...,m)分解质因数呢

    仍然假设质数K,可以求出最大的t,以及一个常数c(1<=c<K),使得 n+1<=c*K^t<=m
    那么lcm(n+1,n+2,...,m)分解质因数中一定而且最多有t个质数K连乘。

    比如说质数3,n=16,m=22,可以求的c=2,t=2,即17<=2*3^2=18<=22,这样lcm(17,18,19,20,21,22)中最多有2个质数3连乘

    既然知道怎么求lcm(n+1,n+2,..,m)和lcm(1,2,..,m)了

    来探讨一下怎么求最小的m吧

    我们想让这两个lcm分解质因数后完全一样,也就是说连乘的质数个数也完全相等。

    也就是说,对于每个质数K都可以满足,存在c和最大的t 使得n+1<=c*K^t<=m

    对于大于n小于m的质数,我们假设是P,那么一定n+1<=P<=m,一定可以满足条件

    所以我们就只看小于等于n的质数就可以了

    因为要使每个小于N的质数K,都存在c和最大的t 使得n+1<=c*K^t<=m,

    我们枚举每一个质数,并求得c和t,使得刚好c*K^t>=n,

    答案就取最大的c*K^t,即 max( c*K^t )

    这样lcm(1,2,...,m)和lcm(n+1,n+2,...,m)的分解质因数后均至少有t个质数K。

    如果最终m有 k^(t+1)<=m,那么这个K^(t+1)>n一定成立,故仍满足条件

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<stack>
    #include<vector>
    #include<queue>
    #include<string>
    #include<sstream>
    #define eps 1e-9
    #define ALL(x) x.begin(),x.end()
    #define INS(x) inserter(x,x.begin())
    #define FOR(i,j,k) for(int i=j;i<=k;i++)
    #define MAXN 1005
    #define MAXM 40005
    #define INF 0x3fffffff
    using namespace std;
    typedef long long LL;
    LL i,j,k,n,m,x,y,T,big,cas,num;
    bool flag;
    
    LL cur,ans;
    
    
    bool prim[2000005];
    LL ver[2000005]; 
    void GetPrim(LL size)
    {
        LL m=sqrt(size+0.5);
        memset(prim,0,sizeof(prim));//可以根据情况进行清空操作 
        num=0;//把找到的质数存入ver数组中,num为ver数组的长度 
        
        //如果要获得质数数组,i就枚举到size,如果仅仅是prim数组,就枚举到m 
        for (LL i=2;i<=size;i++)
        {
            if (!prim[i])
            {
                ver[++num]=i;
                if (i<=m) for (LL j=i*i;j<=size;j+=i) prim[j]=1;
            }
        }
    }
    
    class MissingLCM
    {
            public:
            int getMin(int N)
            {
                LL n=N;
                GetPrim(n);
                LL ans=n+1;
                for (i=num;i>=1;i--)
                {
                    LL u=ver[i];
                    for (j=1;j*u<=n;j*=u);
                    
                    ans=max(ans,(n/j+1)*j);
                }
                return ans;
            }
    };
  • 相关阅读:
    如何通过命令行窗口查看sqlite数据库文件
    eclipse自动补全的设置
    文本装饰
    注释和特殊符号
    文本装饰
    网页背景
    通过ArcGIS Server admin 查看和删除已注册的 Web Adaptor
    通过 ArcGIS Server Manager 查看已安装的 Web Adaptor
    通过 ArcGIS Server Manager 验证 DataStore
    Windows上安装ArcGIS Enterprise——以 Windows Server 2012 R2上安装 ArcGIS 10.8为例
  • 原文地址:https://www.cnblogs.com/zhyfzy/p/4571180.html
Copyright © 2011-2022 走看看