Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

普通的质因数分解过了,pollard rho的brent优化报RE,自已把1-2^20全部遍历正常出结果,速度还快

Posted by cavs at 2020-07-03 15:04:33 on Problem 3421

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <set>
#include <utility>
#include <vector>

using namespace std;

const int MAX = (1 << 20) + 5;

int n;
pair<short, int> dp[MAX];
int lp[MAX + 1];
vector<int> primes;

void precomputeprime() {
    memset(lp, 0, sizeof(int) * MAX);
    lp[1] = 1;
    for (int i = 2; i <= MAX; ++i) {
        if (lp[i] == 0) {
            lp[i] = i;
            primes.push_back(i);
        }
        for (int j = 0; j < (int)primes.size() && primes[j] <= lp[i] && i * primes[j] <= MAX; ++j)
            lp[i * primes[j]] = primes[j];
    }
}

inline int int_abs(int a) {
    return a >= 0 ? a : -a;
}

int gcd(int x, int y) {
    if (y == 0) return x;
    return gcd(y, x % y);
}

int mult(int a, int b, int mod) {
    return int(long(a) * b % mod);
}

int f(int x, int c, int mod) {
    return (mult(x, x, mod) + c) % mod;
}

int brent(int n, int c = 120) {
    int g = 1;
    int q = 1;
    int xs, x, y;
    x = rand() % (n - 1) + 1;
    int m = rand() % 128 + 1;
    int l = 1;
    while (g == 1) {
        y = x;
        for (int i = 1; i < l; ++i) x = f(x, c, n);
        int k = 0;
        while (k < l && g == 1) {
            xs = x;
            for (int i = 0; i < m && i < l - k; ++i) {
                x = f(x, c, n);
                q = mult(q, int_abs(y - x), n);
            }
            g = gcd(q, n);
            k += m;
        }
        l *= 2;
    }
    if (g == n) {
        do {
            xs = f(xs, c, n);
            g = gcd(int_abs(xs - y), n);
        } while (g == 1);
    }
    return g;
}

void findfactors(int n, set<int>& factors) {
    if (n == 1) return;
    while (lp[n] != n) {
        int p = brent(n);
        if (lp[p] == p) factors.insert(p);
        else findfactors(p, factors);
        while (n % p == 0) n /= p;
    }
    if (n > 1) factors.insert(n);
}

void calchain(int n) {
    if (dp[n].first > 0) return;
    if (lp[n] == n) {
        dp[n] = make_pair(2, 1);
        return;
    }
    set<int> factors;
    findfactors(n, factors);
    dp[n] = make_pair(0, 0);
    for (set<int>::iterator j = factors.begin(); j != factors.end(); ++j) {
        int k = n / *j;
        calchain(k);
        if (dp[k].first + 1 == dp[n].first)
            dp[n].second += dp[k].second;
        else if (dp[k].first + 1 > dp[n].first) {
            dp[n] = dp[k];
            ++dp[n].first;
        }
    }
}

int main() {
    // freopen("in.txt", "r", stdin);
    precomputeprime();
    dp[1] = make_pair(1, 1);
    dp[2] = make_pair(2, 1);
    while (scanf("%d", &n) != EOF) {
        calchain(n);
        printf("%d %d\n", dp[n].first - 1, dp[n].second);
    }

    return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator