UESTC 618 無平方因子數 (容斥 + 莫比烏斯反演)
阿新 • • 發佈:2019-01-26
無平方因子數
Submit Status
無平方因子數即對於任意一個素數p,p2都不會整除那個數,如1 , 5=5 , 15=3×5都是無平方因子數,而20=22×5不是。現在給定一個n (1≤n<1012) ,求區間[1,n]中無平方因子數的個數。
Input
第一行有個整數T,代表資料組數(T≤10)
接下來有T行,每行有個整數n (1≤n<1012)
Output
輸出T行,每行輸出一個整數代表區間[1,n]內的無平方因子數的個數。
Sample Input
3
1
10
7
Time Limit: 4000/2000MS (Java/Others)
Memory Limit: 65535/65535KB (Java/Others)
Submit Status
無平方因子數即對於任意一個素數p,p2都不會整除那個數,如1 , 5=5 , 15=3×5都是無平方因子數,而20=22×5不是。現在給定一個n (1≤n<1012) ,求區間[1,n]中無平方因子數的個數。
Input
第一行有個整數T,代表資料組數(T≤10)
接下來有T行,每行有個整數n (1≤n<1012)
Output
輸出T行,每行輸出一個整數代表區間[1,n]內的無平方因子數的個數。
Sample Input
3
1
10
30
Sample Output
7
19
Source
UESTC Training for Math
題目分析:又是無平方因子數,比BZOJ那題簡單很多,直接算就行了,參照BZOJ 2440
#include <cstdio> #include <cstring> #include <algorithm> #define ll long long using namespace std; int const MAX = 1e6 + 5; int mob[MAX], p[MAX]; bool prime[MAX]; void Mobius() { int pnum = 0; memset(prime, true, sizeof(prime)); mob[1] = 1; for(int i = 2; i < MAX; i++) { if(prime[i]) { p[pnum ++] = i; mob[i] = -1; } for(int j = 0; j < pnum && i * p[j] < MAX; j++) { prime[i * p[j]] = false; if(i % p[j] == 0) { mob[i * p[j]] = 0; break; } mob[i * p[j]] = -mob[i]; } } } ll cal(ll n) { ll cnt = 0; for(ll i = 1; i * i <= n; i++) cnt += (ll) mob[i] * (n / (i * i)); return cnt; } int main() { Mobius(); int T; scanf("%d", &T); while(T --) { ll n; scanf("%lld", &n); printf("%lld\n", cal(n)); } }