229 lines
4.3 KiB
C++
229 lines
4.3 KiB
C++
|
/*
|
||
|
* 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
|
||
|
|