码迷,mamicode.com
首页 > 其他好文 > 详细

Vijos1889 天真的因数分解

时间:2016-07-09 23:43:00      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:

 

描述

小岛: 什么叫做因数分解呢?
doc : 就是将给定的正整数n, 分解为若干个素数连乘的形式.
小岛: 那比如说 n=12 呢?
doc : 那么就是 12 = 2 X 2 X 3 呀.
小岛: 呜呜, 好难, 居然素数会重复出现, 如果分解后每一个素数都只出现一次, 我就会.

wish: 这样来说, 小岛可以正确分解的数字不多呀.
doc : 是呀是呀.
wish: 现在问题来了, 对于给定的k, 第 k 个小岛无法正确分解的数字是多少?

格式

输入格式

输入只有一行, 只有一个整数 k.

输出格式

输出只有一行, 只有一个整数, 表示小岛无法正确分解出来的第k个数字.

样例1

样例输入1

 
10

样例输出1

 
27

限制

对于30%的数据, k <= 2,000,000
对于100%的数据, 1 <= k <= 10,000,000,000

提示

前 10 个小岛无法正确分解出来的数字依次是: 4 8 9 12 16 18 20 24 25 27

 

莫比乌斯反演

小于x的可以正确分解的数字个数是 Σmu[i]*(x/i^2),算不能分解正确的只要把mu反一下就行

AC记录喜+1

 

注意:此代码目前只过了样例,还没有提交测评,不具有可信度。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int mxn=300010;
 8 int pri[mxn];
 9 int mu[mxn];
10 bool mark[mxn];
11 int cnt=0;
12 long long k;
13 void getmu(){
14     int i,j;
15     mu[1]=1;
16     for(i=2;i<=mxn;i++){
17         if(!mark[i]) pri[++cnt]=i,mu[i]=1;
18         for(j=1;j<=cnt && pri[j]*i<mxn;j++){
19             mark[pri[j]*i]=1;
20             if(i%pri[j]==0){
21                 mu[i*pri[j]]=0;
22                 break;    
23             }
24             else mu[i*pri[j]]=-mu[i];
25         }
26     }
27     return;
28 }
29 int calc(int x){
30     long long ans=0,m;
31     m=sqrt(x);
32     for(long long i=2;i<=m;i++){
33         ans+=x/(i*i)*mu[i];
34     }
35     return ans;
36 }
37 int main(){
38     long long ans;
39     getmu();
40     scanf("%d",&k);
41     long long l=k,r=1e10;
42     while(l<=r){
43         int mid=(l+r)>>1;
44         if(calc(mid)>=k)ans=mid,r=mid-1;
45         else l=mid+1;
46     }
47     printf("%d\n",ans);
48     return 0;
49 }

 

Vijos1889 天真的因数分解

标签:

原文地址:http://www.cnblogs.com/SilverNebula/p/5656813.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!