Inverse function

Given n, I want to find I am such that phi(i) = n. n <= 100,000,000. The maximum value i = 202918035 for n = 99683840. I want to solve this problem

My approach is to pre-compute the totality function of all numbers with maximum value i. To do this, I first find all primes to the maximum iusing an eratronium sieve. The precision of primes is recorded during the sieve. Then using

enter image description here

Then I look for the input number in the array phiand output the result for output. But it limits the time. What else can be optimized in the preliminary calculation, or is there a better way to do this?

My code is:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

using namespace std;

int* Prime = (int*)malloc(sizeof(int) * (202918036 >> 5 + 1));
int* pos = (int*)malloc(sizeof(int) * (11231540));
int* phi = (int*)malloc(sizeof(int) * 202918036);

#define prime(i) ((Prime[i >> 5]) & (1 << (i & (31))))
#define set(j) (Prime[j >> 5] |= (1 << (j & (31))))
#define LIM 202918035
#define SLIM 14245

int sieve() {
    int i, j, m, n, t, x, k, l, h;
    set(1);
    phi[0] = 0;
    phi[1] = 0;
    pos[1] = 2;
    phi[2] = 1;
    pos[2] = 3;
    phi[3] = 2;
    for (k = 2, l = 3, i = 5; i <= SLIM; k++, i = 3 * k - (k & 1) - 1)
    if (prime(k) == 0) {
        pos[l++] = i;
        phi[i] = i - 1;
        for (j = i * i, h = ((j + 2) / 3); j <= LIM; h += (k & 1) ? (h & 1 ? ((k << 2) - 3) : ((k << 1) - 1)) : (h & 1 ? ((k << 1) - 1) : ((k << 2) - 1)), j = 3 * h - (h & 1) - 1)
        set(h);
    }

    i = 3 * k - (k & 1) - 1;
    for (; i <= LIM; k++, i = 3 * k - (k & 1) - 1)
    if (prime(k) == 0) {
        pos[l++] = i;
        phi[i] = i - 1;
    }
    return l;
}

int ETF() {
    int i;
    for (i = 4; i < LIM; i++) {
        if (phi[i] == 0) {
            for (int j = 1; j < i; j++) {
                if (i % pos[j] == 0) {
                    int x = pos[j];
                    int y = i / x;
                    if (y % x == 0) {
                        phi[i] = x * phi[y];
                    } else {
                        phi[i] = phi[x] * phi[y];
                    }
                    break;
                }
            }
        }
    }
}

int search(int value) {
    for (int z = 1; z < LIM; z++) {
        if (phi[z] == value) return z;
    }
    return -1;
}


int main() {

    int m = sieve();

    int t;
    ETF();

    scanf("\n%d", &t);
    while (t--) {
        int n;
        scanf("%d", &n);
        if (n % 2 == 1) {
            printf("-1\n");
        } else {
            int i;
            i = search(n);
            if (i == -1) printf("-1\n");
            else printf("%d\n", i);
        }

    }
    return 0;
}
+5
source share
1 answer

it

     for(int j=1;j<i;j++)
     {            
        if(i%pos[j]==0)
        {

, i . O(n^2/log^2 n), n/log n , n, i , i.

( , , ), [ ] , . , , , . , ,

phi[i] = p*phi[i/p]

i

phi[i] = (p-1)*phi[i/p]

.

- O(n*log n) (, O(n*log log n), ] .

,

int search(int value) {
    for (int z = 1; z < LIM; z++) {
        if (phi[z] == value) return z;
    }
    return -1;
}

. , O (1) .

+2

All Articles