1. 程式人生 > >bzoj 2440 完全平方數

bzoj 2440 完全平方數

int close amp bsp play 莫比烏斯函數 題意 images ...

這是一道論文題。

題意:選出第k個無平方因子的數。

思路:二分答案。

某一個區間的無平方因子的數的個數怎麽求呢? 可以篩。

這裏可以莫比烏斯。

首先什麽是莫比烏斯函數呢?

技術分享

回到本題:

他是一個莫比烏斯函數的應用。

對於1~ mid 中,不含平方因子的個數為:

n - sum(i^2) 其中 i 為素數。

含不含平方因子:就是將 N 質因數分解,只有u(n) != 0的值才是不含質因數因子的。但是開不來10^9的數組,來遍歷u(n),用素數優化。

例如: 4,9,4n,9n,這些數得刪掉,4的倍數的個數 為 n/4 n/9,

所謂平方因子也是 一些素數的平方得到的。

那麽這裏就有一個容斥定理,n - 每個質數的平方因子的數的倍數,(這裏不用算素數,因為有莫比烏斯函數做系數)+每兩個質數的乘積的平方因子的數的倍數-每三個... ...

例如:刪掉了4的倍數,9的倍數,那麽36就被刪了兩次,(容斥定理)

技術分享
#include <bits/stdc++.h>

using namespace std;

const int n = 1e+5;

typedef long long ll;

int mu[n];

void getMu() {
    for(int i=1;i<=n;i++) {
        
int target = i == 1? 1: 0; int delta = target - mu[i]; mu[i] = delta; for(int j=i+i;j<=n;j+=i) mu[j] +=delta; } } ll k; ll calc(ll mid) { ll sq = sqrt(mid); ll ans = 0; for(ll i=1;i<=sq;++i) { ans+=mu[i]*(mid/(i*i)); }
return ans; } int main(int argc, char const *argv[]) { getMu(); ll t; scanf("%I64d",&t); for(ll z=0;z<t;++z) { scanf("%I64d",&k); ll l = 0,r = k*2; while(l<r) { ll mid = (l+r)/2; if(calc(mid)>=k) r = mid; else l = mid + 1; } cout<<l<<endl; } return 0; }
View Code

bzoj 2440 完全平方數