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;
            }
    };
  • 相关阅读:
    java url 获取文件_[转]从URL获取文件保存到本地的JAVA代码,url 请求设置http请求头
    解决Mybatis中出现的Invalid bound statement (not found)问题
    使用多线程往LIST添加数据 线程安全list
    spring BeanUtils 工具实现对象之间的copy 属性复制,属性拷贝
    idea 打开Service窗口一个管理所有服务的地方
    java实现大文件下载(http方式)
    Java @Override注解写与不写的区别
    Linux下C++共享内存
    Linux配置开机自启
    Linux中zsh出现 zsh: corrupt history file /XXX/.zsh_history解决办法
  • 原文地址:https://www.cnblogs.com/zhyfzy/p/4571180.html
Copyright © 2011-2022 走看看