#define _CRT_SECURE_NO_WARNINGS 1//jerry99的数列 #include<bits/stdc++.h> int prime[40000] = { 0 }; int pri[6000] = { 0 }; int nums[3000] = { 0 }; int mem[3000] = { 0 }; int jiecheng[40000*1000] = { 0 }; void pre() {//标记质数1~50000 prime[0] = prime[1] = 1; for (int i = 2; i < 40000; i++) { for (int j = 2 * i; j < 40000; j += i) { prime[j] = 1; } } int k = 0; for (int i = 0; i < 40000; i++) { if (!prime[i]) pri[k++] = i;//存放在num数组里备用 } } int div2(int n) { memset(mem, 0, 6000); int k = 0, d, num = 0, origin = n; for (int i = 0; n != 1; i++) { d = pri[i]; while (n % d == 0) { mem[k]++; n /= d; } k++; if (k >= 5133&&n>50000) return 1; } return 0; } int main() { pre();//筛出质数 //提前分解好1~20000阶乘质因数 int t, n, m; for (n = 1; n < 40000; n++) { int k = 0, d, num = 0, origin = n; for (int i = 0; pri[i]<=n; i++) { d = pri[i]; while (origin != 1&&origin%d==0) { nums[k]++; origin /= d; } k++; } for (int p = 0; p < k; p++) { *(jiecheng+1000*n+p) += (*(jiecheng+1000*(n-1)+p)+ nums[p]);//递推地计算质因数分解结果 //printf("%d ", jiecheng[n][p]);//数组一维化 }//printf("\n"); memset(nums, 0, 3000*4); } for (int i = 1; i < 10; i++) { for (int j = 0; j < 10; j++) { printf("%d ", jiecheng[i][j]); }printf("\n"); } scanf("%d", &t); int judge; while (t > 0) { memset(mem, 0, 3000*4); scanf("%d%d", &n, &m);//n分母,m分子 judge = div2(n);//把分母质因数分解 if (judge&&n>40000) {//如果n分解后的质因数是个超级大(>50000)的质数 if (m < n) printf("0\n"); else { printf("%d\n", m - n + 1); } } else {//小于50000的质数或者不是质数的10^9以内的 int cnt, j = 0; for (cnt = 1; cnt < n;) { //printf("%d ", *(jiecheng + 1000 * cnt + j)); while (mem[j] > * (jiecheng + 1000 * cnt + j)) { cnt++;//每一位幂次进行比较 } //printf("%d ", *(jiecheng + 1000 * cnt + j)); if (mem[j] <= *(jiecheng + 1000 * cnt + j)) { j++;//比较完一个每次进入下一个幂次 } if (!mem[j] && j == n) { break; } } /*for (int i = 1; i < n; i++) { for (int j =0 ; j < 10; j++) { printf("%d ", *(jiecheng +1000 * i + j)); } }*/ //printf("比%d大的最小阶乘是 %d !\n", n, cnt); if (cnt > m + 1) printf("0\n"); else printf("%d\n", m - cnt + 1); t--; } } return 0; }