2

On m'a posé la question suivante dans une interview:très grand nombre modulo nombre premier

Comment résoudre ceci: (!! (3000000)/(30)^100000)% (tout premier pas.)

J'ai codé le programme C pour celui-ci en utilisant la force brute, mais je suis sûr qu'il ne s'attendait pas à cela. Des suggestions pour les solutions?

+0

Si "^" signifie "augmenter à la puissance", alors je pense que 3E6!/30!^1E5 est inférieur à un. Si vous interprétez "/" comme "division entière" alors nous obtenons 0, donc il reste 0 après le modulo. – redtuna

+0

D'accord, mais l'intervieweur m'a demandé de coder ceci. Peut-être s'attendait-il à ce que je formule un théorème. – Gaurav

+1

réponse ---> 10 IMPRIMER "0". Et puis une discussion sur le tableau blanc sur pourquoi. – redtuna

Répondre

0

3000000! = 1*2*3*4*5*..*8*...*16*...*24*...*32*...40*...*64*...*3000000

Peut-on compter le nombre de s dans le résultat? Oui, chaque puissance de contribue un à chacun de ses multiples. Donc, le nombre total de s dans la factorisation de n! est n/2 + n/4 + n/8 + n/16 + n/32 + .../ est une division entière et les conditions se résument alors qu'ils sont supérieurs à 0:

fnf n f = -- number of `f` factors in `n!` 
    sum . takeWhile (>0) . tail . iterate (`div` f) $ n 

(écrire le pseudocode in Haskell). quand f*f < n, il y aura plus d'une entrée à résumer. Pour plus de f s, il n'y aura qu'une seule entrée à additionner, à savoir. n `div` f.

Ainsi, la factorisation de n! se trouve que

factfact n = -- factorization of n! as [ (p,k) ... ] for n! = PROD p_i^k_i 
    let 
    (ps,qs) = span (\p-> p*p <= n) primes -- (before, after) 
    in 
    [(f, fnf n f) | f <- ps] ++ 
    [(f, n `div` f) | f <- takeWhile (<= n) qs] 

Maintenant, factorisation de ! a 10 facteurs:

> factfact 30 
[(2,26),(3,14),(5,7),(7,4),(11,2),(13,2),(17,1),(19,1),(23,1),(29,1)] 

Le ième puissance de celui-ci vient de chacun de ses coefficients de facteur multiplié par . ! Quand nous prenons la factorisation de , ses premiers termes sur 216816 au total, sont les suivants:

> factfact 3000000 
[(2,2999990),(3,1499993),(5,749998),(7,499996),(11,299996),(13,249998), 
(17,187497),(19,166665),(23,136361),(29,107142),(31,99998), ... 

donc après la division lorsque nous soustrayons la deuxième de la première ne manquent ni annulé complètement:

[(2,399990),(3,99993),(5,49998),(7,99996),(11,99996),(13,49998), 
(17,87497),(19,66665),(23,36361),(29,7142),(31,99998), ... 

Donc, pour tout premier inférieur à 3000000 le reste est 0. Et s'il est plus grand, p > 3000000? Ensuite, exponentiation modulaire mod p et multiplication mod p pour cette factorisation, que nous avons trouvé ci-dessus, doit être utilisé. Il y a beaucoup de réponses à propos de ça, sur SO. Bien sûr, dans le code de production (pour un langage de programmation non fainéant), nous ne construirions pas la liste de factorisation intermédiaire, mais traiterions chaque prime en dessous de 3000000, un par un (pas besoin d'un paresseux la langue).

+0

Il sera vraiment utile si vous pouvez s'il vous plaît pointer vers la réponse la plus pertinente présente sur SO pour p> 3000000 en utilisant l'exponentiation mod mod p. (Ce concept est nouveau pour moi). – Gaurav

+0

@Gaurav essayez [ces réponses] (http://stackoverflow.com/search?q=user%3A448810+%5Bprimes%5D+is%3Aanswer+modular). Ou [ces] (http://stackoverflow.com/search?q=user%3A1011995+%5Bprimes%5D+is%3Aanswer+modular). –

+1

@Gaurav vous pouvez simplement taper "multiplication modulaire" ou "exponentiation modulaire" dans une boîte de recherche ici sur SO dans le coin supérieur droit d'une page. Le premier (de 1088) qui apparaît, a l'air correct aussi. –

Questions connexes