/* * YOUR INFO HERE! */ // FINAL VERSION: typedef unsigned long long bigint; struct Sieve_Array{ bool *is_composite; bigint size; }; struct Primes{ bigint *primes; int count, max; }; struct Sieve{ Sieve_Array sieve; Primes ps; int i; int w; }; void extend_sieve(Primes ps, Sieve_Array sieve, int start){ int q,p,j,n,m; for (q = 1; q < ps.count; ++q){ p = ps.primes[q]; j = start; n = 2*j + 3; m = (n/p)*p; if (n != m){ n = m+p; if (n % 2 == 0){ n += p; } j = (n-3)/2; } for (; j < sieve.size; j += p){ sieve.is_composite[j] = 1; } } } int sieve_partial(Primes *ps_, Sieve_Array sieve, int start){ Primes ps = *ps_; int i=start,n,j; for (; i < sieve.size; ++i){ if (!sieve.is_composite[i]){ n = i*2 + 3; ps.primes[ps.count++] = n; for (j = i + n; j < sieve.size; j += n){ sieve.is_composite[j] = 1; } if (ps.count == ps.max){ ++i; break; } } } ps_->count = ps.count; return i; } // size of primes >= which_prime // size of sieve >= size > 0 void begin_sieve(Sieve *s, int prime_size, int size){ s->sieve.size = size; s->ps.count = 1; s->ps.max = prime_size; s->ps.primes[0] = 2; s->i = 0; s->w = prime_size; } inline bool sieve_step(Sieve *s){ s->i = sieve_partial(&s->ps, s->sieve, s->i); return (s->ps.count != s->w); } inline void sieve_grow(Sieve *s, Sieve_Array new_sieve){ extend_sieve(s->ps, new_sieve, s->sieve.size); s->sieve = new_sieve; } inline int sieve_init_size(int which_prime){ return which_prime*5; } inline int sieve_new_size(Sieve s){ return s.sieve.size + s.w * (1 + ((s.w - s.ps.count) / 1000)); } #ifdef EULER_PROBLEM // BUILDING AREA: struct Euler_In{}; struct Euler_Result{ int number; }; int count_divisors(int x, int *d, Primes ps){ int dc = 0; int c,p,i,j; p = ps.primes[0]; for (i = 0; i < ps.count && p < x; ++i){ p = ps.primes[i]; c = 1; while (x % p == 0){ x /= p; ++c; } if (c > 1){ d[dc++] = c; } } c = 1; for (j = 0; j < dc; ++j){ c *= d[j]; } return c; } int count_divisors(int x, int *d){ int dc = 0; int c,p,j; c = 1; while (x % 2 == 0){ x /= 2; ++c; } if (c > 1){ d[dc++] = c; } for (p = 3; p <= x; p += 2){ c = 1; while (x % p == 0){ x /= p; ++c; } if (c > 1){ d[dc++] = c; } } c = 1; for (j = 0; j < dc; ++j){ c *= d[j]; } return c; } inline Euler_Result euler_main(Euler_In in){ int d[500]; int max = 1600; int *divs = (int*)malloc(sizeof(int)*max); divs[0] = 0; divs[1] = 1; divs[2] = 2; int x=1,n=2,c=0,a,b; a=1; b=1; while (1){ if (c >= 500){ break; } ++n; divs[n] = count_divisors(n, d); b += 2; x += 2*a; c = divs[a]*divs[b]; if (c >= 500){ break; } ++n; if (n >= max){ int new_max = max*2; int *new_divs = (int*)malloc(sizeof(int)*new_max); memcpy(new_divs, divs, sizeof(int)*max); free(divs); divs = new_divs; max = new_max; } divs[n] = count_divisors(n, d); a += 1; x += b; c = divs[a]*divs[b]; } Euler_Result result; result.number = x; return result; } void euler_print(Euler_Result answer, Euler_In in){ printf("%d\n", answer.number); } #define EULER_CHECK bool euler_check(Euler_Result answer, Euler_In in){ bool result; int a = 76576500; printf("answer = %d\n", a); result = (a == answer.number); return result; } #endif