bzoj 2440 完全平方數
阿新 • • 發佈:2017-07-28
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++) {View Codeint 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; }
bzoj 2440 完全平方數