ACM ICPC Praktikum Kapitel 7: Zahlentheorie Übersicht • • • • Primzahlen Größter gemeinsamer Teiler Kleinstes gemeinsames Vielfaches Modulo Arithmetik Primzahlen Test, ob x eine Primzahl ist: • Teste alle Zahlen von 1 bis x • x ausreichend, da für jeden Teiler y von x gilt, dass y ¢ z = x für ein z, und entweder y oder z höchstens x sein kann Primfaktorisierung 1. 2. 3. 4. prime_factorization(long x) { long i; long c; 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. } /* counter */ /* remaining product to factor */ c = x; while ((c % 2) == 0) { printf("%ld\n",2); c = c / 2; } i = 3; while (i <= (sqrt(c)+1)) { if ((c % i) == 0) { printf("%ld\n",i); c = c / i; } else i = i + 2; } if (c > 1) printf("%ld\n",c); Größter gemeinsamer Teiler • Problem: gegeben Zahlen a und b, finde größte Zahl c, so dass c|a und c|b. • c: ggT(a,b) • ggT(a,a) = ggT(a,0) = ggT(0,a) = a • a<b: ggT(a,b) = ggT(a, b mod a) (b=k ¢ a + r, dann ggT(a,b) | r) • a>b: ggT(a,b) = ggT(a mod b, b) Größter gemeinsamer Teiler 1. long gcd(long p, long q) /* compute gcd(p,q) */ 2. { 3. if (q == 0) return(p); 4. if (p == 0) return(q); 5. if (q > p) return(gcd(q % p,p)); 6. if (p > q) return(gcd(q, p % q)); 7. return(q); /* p=q */ 8. } Größter gemeinsamer Teiler 1. /* Find the gcd(p,q) and x,y such that p*x + q*y = gcd(p,q) 2. long gcd(long p, long q, long *x, long *y) 3. { 4. long x1,y1; /* previous coefficients */ 5. long g; /* value of gcd(p,q) */ 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. } if (q > p) return(gcd(q,p, &y, &x)); if (q == 0) { *x = 1; *y = 0; return(p); } g = gcd(q, p%q, &x1, &y1); *x = y1; *y = (x1 - floor(p/q)*y1); return(g); */ Kleinstes gemeinsames Vielfaches • Kleinstes gemeinsames Vielfaches von a und b: kgV(a,b) (englisch: lcm(a,b)) • Regel: a ¢ b = ggT(a,b) ¢ kgV(a,b) Modulo Arithmetik • Negative Zahlen: -x mod n = n-(x mod n) • Addition: (x+y) mod n = ((x mod n) + (y mod n)) mod n • Multiplikation: x ¢ y mod n = ((x mod n) ¢ (y mod n)) mod n xy mod n = (x mod n)y mod n = [((x mod n)y1) mod n) ¢ ((x mod n)y2) mod n)] mod n mit y = y1 + y2 Anwendungen • Finde letzte Ziffer einer großen Zahl (z.B. 2100) • RSA Verschlüsselung • Kalenderberechnungen