AcWing - 197 - factorial decomposition

https://www.acwing.com/problem/content/199/

Solution n! Prime factorization, n magnitude 1e6.

One of the simplest idea is violent decomposition of the quality factor for each number, complexity is too high.

In other words an idea, when the batch processing required to determine the minimum number of each prime factor linear sieve, then this number only needs to be the prime factorisation log level.

191ms:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MAXN = 1e6;
int minp[MAXN + 5];
int p[MAXN + 5], ptop;
void sieve(int n) {
    minp[1] = 1;
    for(int i = 2; i <= n; i++) {
        if(!p[i]) {
            p[++ptop] = i;
            minp[i] = i;
        }
        for(int j = 1, t; j <= ptop && (t = i * p[j]) <= n; j++) {
            p[t] = 1;
            minp[t] = p[j];
            if(i % p[j])
                ;
            else
                break;
        }
    }
}

int cnt[MAXN + 5];

int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    int n;
    scanf("%d", &n);
    sieve(n);
    for(int i = 2; i <= n; ++i) {
        int tmp = i;
        while(tmp > 1) {
            ++cnt[minp[tmp]];
            tmp /= minp[tmp];
        }
    }

    for(int i = 2; i <= n; ++i) {
        if(cnt[i])
            printf("%d %d\n", i, cnt[i]);
    }
}

There is another idea complexity is the same, but does not require so much division. N is clearly within the factor p has exactly n / p number, and two factor p has exactly n / (p ^ 2) th, is calculated by multiplying the direct theoretically faster.

43ms:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int MAXN = 1e6;
int p[MAXN + 5], ptop;
void sieve(int n) {
    for(int i = 2; i <= n; i++) {
        if(!p[i]) {
            p[++ptop] = i;
        }
        for(int j = 1, t; j <= ptop && (t = i * p[j]) <= n; j++) {
            p[t] = 1;
            if(i % p[j])
                ;
            else
                break;
        }
    }
}

int cnt[MAXN + 5];

int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    int n;
    scanf("%d", &n);
    sieve(n);
    for(int i = 1; i <= ptop; ++i) {
        int ans = 0;
        for(ll j = p[i]; j <= n; j *= p[i])
            ans += n / j;
        printf("%d %d\n", p[i], ans);
    }
}

Guess you like

Origin www.cnblogs.com/Inko/p/11528776.html