jerry99的数列--阶乘

#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;
}

 

上一篇:ptr_fun/mem_fun/mem_fun_ref


下一篇:stl使用中的经验(十四)--ptr_fun、mem_fun、mem_fun_ref