HDU 2204 Eddy s愛好 容斥

2021-08-08 22:13:11 字數 1184 閱讀 3422

ignatius 喜歡收集蝴蝶標本和郵票,但是eddy的愛好很特別,他對數字比較感興趣,他曾經一度沉迷於素數,而現在他對於一些新的特殊數比較有興趣。 

這些特殊數是這樣的:這些數都能表示成m^k,m和k是正整數且k>1。 

正當他再度沉迷的時候,他發現不知道什麼時候才能知道這樣的數字的數量,因此他又求助於你這位聰明的程式設計師,請你幫他用程式解決這個問題。 

為了簡化,問題是這樣的:給你乙個正整數n,確定在1到n之間有多少個可以表示成m^k(k>1)的數。 

input

本題有多組測試資料,每組包含乙個整數n,1<=n<=1000000000000000000(10^18). 

output

對於每組輸入,請輸出在在1到n之間形式如m^k的數的總數。 

每組輸出佔一行。

題解: 由於2^60>1^18 故最初想法是列舉n的2~60次方根容斥.

注意到a^mn = (a^m)^n, 剩下a^m的n次項總可以令n為質數,故直接列舉[2, 60] 的質數即可. 

又注意到有些數字可能被重複計算. 例如3^15這個數在3次方根內已經計算過, 在5次方根又被計算過一次. 

於是這題的想法就完成了: 以60以內的質數為基. 進行容斥.

原始碼:#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

typedef long long ll;

typedef pairp;

const int inf = 0x7fffffff;

const int max_n = 60;

const int max_v = 0;

const int max_m = 0;

const int max_q = 0;

void show(string a, int val)

} int sym = num&1? 1: -1;

ll tmp = (ll)(pow(n, 1.0/k)+eps);

res += tmp*sym;

} return res;

}int main(){

p = sieve(60);

while(cin>>n){

cout<

hdu 2204 Eddy s愛好 容斥

根據指數的質數分解進行容斥 比如 k a 3 且 k b 5,那麼 k c 15 所以 a 的可選個數 加 b的可選個數減去c的可減個數就是總的個數了因為 a 3和b 5有重複的 include include include include include include define ll lo...

HDU 2204 Eddy s愛好 容斥

input 本題有多組測試資料,每組包含乙個整數n,1 n 1000000000000000000 10 18 output 對於每組輸入,請輸出在在1到n之間形式如m k的數的總數。每組輸出佔一行。sample input 10 361000000000000000000sample output...

hdu2204 Eddy s愛好(容斥)

題意 給定n,問有多少個p m k,滿足p n 要求m 1,k 1 資料範圍 n 1e18 解法 顯然列舉m肯定不行,因為m 2 1e18 那麼m 1e9,考慮列舉k,2 60 1e18 因此列舉k最多列舉60個,如果k是乙個合數,那麼k可以拆分為乙個數與質數的乘積 k x p,那麼m k可以變為m...