SCUT - 11 - Designated Player - Prime Factor Decomposition

Keywords: Python

https://scut.online/p/11

T many times, but also want to use mutimap violence to decompose the prime factor of each number. Later, the minimum prime factor for each number was recorded.

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

int n, m, MOD;

const int SIZE = 1e6, SIZEP = 8e4;

int p2[SIZE + 5], p5[SIZE + 5];
int p[SIZEP + 5], ptop;
int minp[SIZE + 5];

void init() {
    for(int i = 2; i <= SIZE; i *= 2) {
        for(int j = i; j <= SIZE; j += i)
            p2[j] ++;
    }
    for(int i = 5; i <= SIZE; i *= 5) {
        for(int j = i; j <= SIZE; j += i)
            p5[j] ++;
    }
    minp[1] = 1;
    for(int i = 2; i <= SIZE; i++) {
        if(!minp[i]) {
            p[++ptop] = i;
            minp[i] = ptop;
        }
        for(int j = 1, t; j <= ptop && (t = i * p[j]) <= SIZE; j++) {
            minp[t] = j;
            if(i % p[j] == 0)
                break;
        }
    }
    //cout<<ptop<<endl;
}


int cntp[SIZEP + 5];

void cnt(int n, int d) {
    while(n != 1) {
        cntp[minp[n]] += d;
        n /= p[minp[n]];
    }
}

int qpow(ll x, int n) {
    ll res = 1;
    while(n) {
        if(n & 1)
            res = res * x % MOD;
        x = x * x % MOD;
        n >>= 1;
    }
    return res;
}

int calc() {
    memset(cntp, 0, sizeof(cntp));
    m = min(n - m, m);
    for(int i = 1; i <= m; ++i) {
        cnt(n - i + 1, 1);
        cnt(i, -1);
    }
    int min10 = min(cntp[1], cntp[3]);
    cntp[1] -= min10, cntp[3] -= min10;
    printf("%d ", min10);
    ll ans = 1;
    for(int i = 1; i <= ptop; ++i)
        ans = ans * (qpow(p[i], cntp[i])) % MOD;
    return ans % MOD;
}

int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    init();
    while(~scanf("%d%d%d", &n, &m, &MOD))
        printf("%d\n", calc());
}

In fact, this is a factorial (DQ method), so the contribution of each quality factor within the factorial can be calculated. Specifically, 2 contributes n/2, 4 contributes n/4 2, 8 contributes n/8 2.

Using the above method, each prime factor contributes a log of 80,000 logns, while my method is 1000,000 logns, and my pretreatment of p2 and p5 is not linear (the latter two white processes are found).

Binary memset, psychotic.

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

int n, m, MOD;

const int SIZE = 1e6, SIZEP = 8e4;
int p[SIZEP + 5], ptop;
int minp[SIZE + 5];

void init() {
    minp[1] = 1;
    for(int i = 2; i <= SIZE; i++) {
        if(!minp[i]) {
            p[++ptop] = i;
            minp[i] = ptop;
        }
        for(int j = 1, t; j <= ptop && (t = i * p[j]) <= SIZE; j++) {
            minp[t] = j;
            if(i % p[j] == 0)
                break;
        }
    }
    //cout<<ptop<<endl;
}

int maxptop;
int cntp[SIZEP + 5];

void cnt(int n, int d) {
    /*while(n != 1) {
        cntp[minp[n]] += d;
        n /= p[minp[n]];
    }*/
    for(int i=1;i<=maxptop;++i){
        int tmp=n;
        while(tmp/=p[i]){
            cntp[i]+=tmp*d;
        }
    }
}

int qpow(ll x, int n) {
    ll res = 1;
    while(n) {
        if(n & 1)
            res = res * x % MOD;
        x = x * x % MOD;
        n >>= 1;
    }
    return res;
}

int calc() {
    maxptop=min(int(lower_bound(p+1,p+1+ptop,n)-p),ptop);
    memset(cntp, 0, sizeof(cntp[0])*(maxptop+1));
    /*m = min(n - m, m);
    for(int i = 1; i <= m; ++i) {
        cnt(n - i + 1, 1);
        cnt(i, -1);
    }*/
    cnt(n,1);
    cnt(m,-1);
    cnt(n-m,-1);
    int min10 = min(cntp[1], cntp[3]);
    cntp[1] -= min10, cntp[3] -= min10;
    printf("%d ", min10);
    ll ans = 1;
    for(int i = 1; i <= maxptop; ++i){
        if(cntp[i])
            ans = ans * (qpow(p[i], cntp[i])) % MOD;
    }
    return ans % MOD;
}

int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    init();
    while(~scanf("%d%d%d", &n, &m, &MOD))
        printf("%d\n", calc());
}

Posted by elkidogz on Thu, 10 Oct 2019 11:03:27 -0700