TOJ 3653 第k互素數

2021-10-24 08:59:23 字數 1604 閱讀 9813

描述

請你寫乙個程式,計算與m和n都互為素數的數中第k大的數,假如x與y互為素數,那麼x和y的最大公約數必為1。

輸入

第一行包含乙個整數t代表測試資料的組數

每組資料有一行,分別包含m,n,k,其中(0

輸出

對應每組測試資料,每行輸出該組組號和第k個與m,n互為素數的整數

思路:

對於1e9這樣的範圍,乙個乙個算出與m,n互質的數顯然不現實,思考o(log(n))的方法。設p(i)為小於等於i的正整數中與m,n互質數的個數,可以發現p(i)<=p(i+1),這個函式是遞增的,可以用二分來找出第k個與n,m互質的數。二分的下界為1,關於上界可以由素數定理(π(x)~x/ln(x))大致求出小於3e10的質數大約有1,243,550,985個,大於1e9,因此設上界為3e10。

接下來考慮計算p(i)的方法,參考n/2可以求出在1~n中可以被2整除的數量,因此可以求出n,m所有的質因子並利用容斥求出p(i)(加上所有i除以奇數個質數乘積的商然後減去所有i除以偶數個質數乘積的商,最後得到小於等於i中不與n,m互質的個數)。

考慮方案的時間複雜度。設n為質數個數,計算p(i)的複雜度為o(2^(n)),考慮n的最大值,nmax=2×3×5×7×11×13×17×19×23=223,092,870,mmax=29×31×37×41×43=58,642,669,nmax=14。

總複雜度為o(log2(3e10)*2^n)(去掉了計算質數的複雜度)在1<=n<=14的條件下最大值約為395,255,可行。

一開始用遞迴一直超時,後來發現才在求質數組合的時候多了很多重複計算……

#include

using

namespace std;

typedef

long

long ll;

const ll ms=

3e10+5

;int q[15]

,cnt;

void

cook

(int x)

if(xbreak;}

if(x!=

1)q[cnt++

]=x;

}ll m;

ll a[2]

[3500];

ll cul()

,it=0;

a[0]

[0]=

1;int st[2]

[3500]=

; ll ans=

0,tmp;

for(

int i=

0;i} c[it]=0

; it=

!it;

//cout(c[it]==0

)break;}

return ans;

}int

main()

//cout("case %d: %lld\n"

,no,l);}

return0;

}//1 223092870 58642669 1000000000

若有什麼錯誤,歡迎指正^ _ ^ 。

786 第 K 個最小的素數分數

乙個已排序好的表 a,其包含 1 和其他一些素數.當列表中的每乙個 p那麼第 k 個最小的分數是多少呢?以整數陣列的形式返回你的答案,這裡 answer 0 p 且 answer 1 q.示例 輸入 a 1,2,3,5 k 3 輸出 2,5 解釋 已構造好的分數,排序後如下所示 1 5,1 3,2 ...

N個元素陣列中第K大元素

k key.cpp 定義控制台應用程式的入口點。include stdafx.h include include using namespace std template int pivotindex t arr,int first,int last arr first arr last while...

求第K個素數 08年上海交大複試上機題第一題

08年上海交大複試上機題第一題 原題如下 problem a.prime number input file standard input output file standard output time limit 1 second output the k th prime number.inp...