容斥原理求1到n與k互質個數
阿新 • • 發佈:2019-01-31
參考部落格:傳送門
此處的k<=1e9、
#include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #include<vector> using namespace std; typedef long long ll; const int qq = 10005; int num; int prime[qq]; void Analyze(ll x){ for(ll i=2; i*i<=x; ++i) if(x%i==0){ prime[num++] = i; while(x%i==0) x/=i; } if(x>1) prime[num++] = x; } ll slove(ll x){ ll ans = 0; for(ll i = 1; i<(1<<num); ++i){ ll t = 1; int cnt = 0; for(int j=0; j<num; ++j) if(i&(1<<j)) cnt++,t*=prime[j]; if(cnt&1) ans+=x/t; else ans-=x/t; } return ans; }
之前還在想num的大小,前10個最小的質數的乘積是小於3e9, 所以完全不用擔心num的大小
之前還想為什麼i*i > 1e9就出迴圈, 其實想想算數基本定理, 如果x已經迴圈到i*i>1e9了, 說明此時的x就是個質數(x的原始大小最大隻有1e9)
反證法:假設x是一個和數,因為x<=1e9的, 那麼一個和數肯定能分解為一個小的質數乘一個大的質數,但是此時顯然在i後面找不到這麼一對質數是的乘積等於x、
因為i*i本身就>1e9, 後面的數只會比i大、 所以此時x就是個質數