51nod 1434 区间LCM (质因数分解)

分析:考虑从1到n所有数的质因数分解,记录每个质数的最高次数,同理从n+1循环到2n,如果循环到m时每个质因子的次数都不低于所记录的,则跳出循环,结果即为m。先预处理质数,复杂度为O(nlongn)。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=1000005;
 7 int prinum[maxn],len=0,n,m,power[maxn],order[maxn];
 8 int num[maxn];
 9 void CalPri(){
10     memset(order,-1,sizeof(order));
11     for(int i=0;i<maxn;i++)num[i]=i;
12     for(int i=2;i<maxn;i++){
13         if(num[i]==0)continue;
14         prinum[len++]=i;
15         order[i]=len-1;
16         for(int j=2*i;j<maxn;j+=i){
17             num[j]=0;
18         }
19     }
20 }
21 int solve(){
22     int countp=0;
23     if(order[n]!=-1)return 2*n;
24     memset(power,0,sizeof(power));
25     for(int k=0;k<len&&prinum[k]<=n;k++){
26         long long p=prinum[k],p0=prinum[k];
27         countp++;
28         while(p<=n){
29             p*=p0;
30             power[k]++;
31         }
32 //        int k0=k;
33 //        for(int i=0;i<len&&prinum[i]*prinum[i]<=k0;i++){
34 //            if(k0%prinum[i])continue;
35 //            int p=prinum[i],cnt=0;
36 //            if(power[i]==0)countp++;
37 //            while(k0%p==0){
38 //                k0/=p;cnt++;
39 //            }
40 //            power[i]=max(cnt,power[i]);
41 //        }
42 //        if(k0!=1){
43 //            if(power[order[k0]]==0)countp++;
44 //            power[order[k0]]=max(1,power[order[k0]]);
45 //        }
46     }
47     for(int k=n+1;k<=2*n;k++){
48         int k0=k;
49         for(int i=0;i<len&&prinum[i]*prinum[i]<=k0;i++){
50             if(k0%prinum[i])continue;
51             int p=prinum[i],cnt=0;
52             while(k0%p==0){
53                 k0/=p;cnt++;
54             }
55             if(power[i]>0&&power[i]<=cnt){
56                 countp--;
57                 power[i]=0;
58             }
59         }
60         if(k0!=1&&power[order[k0]]==1){
61             countp--;power[order[k0]]=0;
62         }
63         if(!countp){
64             return k;
65         }
66     }
67 }
68 int main(){
69     //freopen("e:\\in.txt","w",stdout);
70     CalPri();
71     int t;
72     cin>>t;
73     while(t--){
74         cin>>n;
75         cout<<solve()<<endl;
76     }
77     return 0;
78 }

 

转载于:https://www.cnblogs.com/7391-KID/p/6909541.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值