|
|
@ -72,6 +72,7 @@ inline static u64 ud_sort(size_t i, size_t j)
|
|
|
|
|
|
|
|
|
|
|
|
return slice[0] + slice[len-1];
|
|
|
|
return slice[0] + slice[len-1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef CATERPILLAR
|
|
|
|
static u64 find_set(u64 target)
|
|
|
|
static u64 find_set(u64 target)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for(register size_t i =0;i<input_sz;i++)
|
|
|
|
for(register size_t i =0;i<input_sz;i++)
|
|
|
@ -90,6 +91,65 @@ static u64 find_set(u64 target)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef CATERPILLAR
|
|
|
|
|
|
|
|
static int cp_outer_bounds(size_t low, size_t high, u64* restrict low0, u64* restrict high0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int mask = 0;
|
|
|
|
|
|
|
|
if(low) {
|
|
|
|
|
|
|
|
*low0 = input[low-1];
|
|
|
|
|
|
|
|
mask|=1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(high<input_sz-1) {
|
|
|
|
|
|
|
|
*high0 = input[high+1];
|
|
|
|
|
|
|
|
mask|=2;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return mask;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static u64 find_set_caterpillar(u64 target)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
u64 value;
|
|
|
|
|
|
|
|
size_t low, high;
|
|
|
|
|
|
|
|
low = high = 0;
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
|
|
|
|
if( (value = csum(low, high)) == target ) {
|
|
|
|
|
|
|
|
printf("%lu\n", ud_sort(low, high));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
u64 blow, bhigh;
|
|
|
|
|
|
|
|
blow = bhigh=0;
|
|
|
|
|
|
|
|
if(value < target) {
|
|
|
|
|
|
|
|
// Add largest outer bound
|
|
|
|
|
|
|
|
switch(cp_outer_bounds(low, high, &blow, &bhigh))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case 0: goto fuck;
|
|
|
|
|
|
|
|
case 1: /* Lower bound is the only possible one to add */
|
|
|
|
|
|
|
|
low -= 1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2: /* Higher bound is the only possible one to add */
|
|
|
|
|
|
|
|
high += 1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
|
|
if(blow <= bhigh) high+=1;
|
|
|
|
|
|
|
|
else low -=1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (value > target) {
|
|
|
|
|
|
|
|
// Remove smallest inner bount
|
|
|
|
|
|
|
|
blow = input[low];
|
|
|
|
|
|
|
|
bhigh =input[high];
|
|
|
|
|
|
|
|
if(blow <= bhigh) low += 1;
|
|
|
|
|
|
|
|
else high -=1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
fuck:
|
|
|
|
|
|
|
|
fprintf(stderr, "No set found\n");
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
map_t def = map_new();
|
|
|
|
map_t def = map_new();
|
|
|
@ -119,7 +179,13 @@ int main()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(!result[i].valid && !(result[i].sum[0] | result[i].sum[1])) {
|
|
|
|
if(!result[i].valid && !(result[i].sum[0] | result[i].sum[1])) {
|
|
|
|
#ifdef PART2
|
|
|
|
#ifdef PART2
|
|
|
|
return find_set(result[i].num);
|
|
|
|
return
|
|
|
|
|
|
|
|
#ifdef CATERPILLAR
|
|
|
|
|
|
|
|
find_set_caterpillar
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
find_set
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
(result[i].num);
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
printf("%lu\n", result[i].num);
|
|
|
|
printf("%lu\n", result[i].num);
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|