算術基本定理解析及其應用
阿新 • • 發佈:2018-12-18
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 typedef long long ll; 5 const ll maxn = 1e6 +7; 6 bool isp[maxn]; 7 int pis[maxn], tot; 8 9 void getp(ll n) {//得到n以內的素數及個數 10 memset(isp, true, sizeof(isp)); 11 for(ll i = 2; i <= n; i++) { 12 if(isp[i]) { 13 tot++; 14 pis[tot] = i; 15 } 16 for(int j = 1; (j <= tot) && (i * pis[j] <= n); j++) { 17 isp[i * pis[j]] = false; 18 if(i % pis[j] == 0) break; 19 } 20 } 21 } 22 ll fac(ll n) {//計算n的正因子個數之和 23 ll now = n;24 ll ans = 1; 25 for(ll i = 1; i <= tot; i++) { 26 if(pis[i] > now)//重要剪枝,每次不必全部試除一遍才結束 27 break; 28 if(now % pis[i] == 0) { 29 int cnt = 0; 30 while(now % pis[i] == 0) { 31 cnt++; 32 now /= pis[i]; 33 }34 ans *= (cnt + 1); 35 } 36 } 37 if(now != 1) 38 ans *= 1 + 1; 39 return ans; 40 } 41 ll solve(ll S, ll b) { 42 if(b * b >= S) 43 return 0; 44 45 ll ans = fac(S);//得到S的正因子個數之和 46 ans /= 2; 47 for(ll i = 1; i < b; i++) { 48 if(S % i == 0) 49 ans--; 50 } 51 return ans; 52 } 53 int main() 54 { 55 ll tot = 0; 56 getp(maxn - 7);//得到maxn - 7以內的素數及個數 57 int T, k = 1; 58 scanf("%d", &T); 59 while(T--) { 60 ll a, b; 61 scanf("%lld%lld", &a, &b); 62 printf("Case %d: %lld\n", k++, solve(a, b)); 63 } 64 return 0; 65 }