Advertisement
a53

triprime

a53
May 5th, 2022
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.24 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <sys/time.h>
  3. #include <time.h>
  4.  
  5. #define DEBUG 0
  6.  
  7. #define MAXN 390000000
  8. // ciur pana la MAXN/6, doar cu numere impare, pe biti, patru octeti pe int
  9. // rezulta MAXN/384 intregi adica 1015626
  10. #define MAXNPER384 1015626
  11. #define NPRIME 4000000 // numarul de numere prime pana la 65 000 000
  12.  
  13. unsigned ciur[MAXNPER384]; // ciur pe biti circa 4MB
  14. int n, prime[NPRIME]; // aici memoram numerele prime circa 16MB
  15.  
  16. static inline int getBit( int x ) {
  17. int i = x >> 6; // 32 bits per intreg dar numai impare
  18. int o = (x >> 1) & 31; // offset in cadrul intregului
  19.  
  20. return (ciur[i] >> o) & 1;
  21. }
  22.  
  23. static inline void setBit( int x ) {
  24. int i = x >> 6; // 32 bits per intreg
  25. int o = (x >> 1) & 31; // offset in cadrul intregului
  26.  
  27. ciur[i] |= (((unsigned)1) << o);
  28. }
  29.  
  30. int triprime( int x ) {
  31. int ntriprime, i, j, k;
  32.  
  33. ntriprime = 0;
  34. i = 0;
  35. while ( i + 2 < n && prime[i] * prime[j = i + 1] * prime[k = i + 2] <= x ) {
  36. while ( prime[i] * prime[j] * prime[k] <= x )
  37. k++;
  38.  
  39. k--; // ajustam k
  40. // pornim cautarea cu doi indici, j creste si k scade
  41. while ( k > j ) { // cata vreme avem un k
  42. ntriprime += k - j; // adunam numarul de perechi
  43. j++; // avansam j
  44. // scadem k pentru ca produsul sa redevina <= x
  45. while ( k > j && prime[i] * prime[j] * prime[k] > x )
  46. k--;
  47. }
  48. i++;
  49. }
  50. return ntriprime;
  51. }
  52.  
  53. int main() {
  54. FILE *fin, *fout;
  55. int a, b, c, i, d, tria, trib;
  56.  
  57. fin = fopen( "triprime.in", "r" );
  58. fscanf( fin, "%d%d", &a, &b );
  59. fclose( fin );
  60.  
  61. // ciurul lui Eratostene pana la b / 6
  62. c = (b / 6) | 63; // vrem sa fie divizibil cu 64
  63. // ciurul lui Eratostene doar pentru numere impare
  64. for ( i = 3; i * i <= c; i += 2 )
  65. if ( getBit( i ) == 0 )
  66. for ( d = i * i; d <= c; d += 2 * i )
  67. setBit( d );
  68.  
  69. // colectam numerele prime
  70. prime[n++] = 2; // stocam 2, este singurul numar prim par
  71. for ( i = 3; i <= c; i += 2 )
  72. if ( getBit( i ) == 0 )
  73. prime[n++] = i;
  74. prime[n] = c + 1; // santinela
  75.  
  76. trib = triprime( b );
  77. tria = triprime( a - 1 );
  78.  
  79. fout = fopen( "triprime.out", "w" );
  80. fprintf( fout, "%d\n", trib - tria );
  81. fclose( fout );
  82.  
  83. return 0;
  84. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement