Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #define is_null(ptr) \
- { \
- if (ptr == NULL) \
- { \
- printf("[ERROR] Pointer at %s:%llu is NULL \n",__FILE__,__LINE__); \
- exit(1); \
- } \
- }
- #define true 1
- #define false 0
- typedef unsigned char byte;
- typedef byte bool;
- #define GOLDEN_RATIO 1.61803398875
- typedef int type;
- #define CREATE_VECTOR_TYPE_H(type) \
- typedef struct vector_##type vector_##type; \
- typedef struct vector_##type { \
- size_t size; \
- size_t size_mem; \
- type* array; \
- void (*push_back)(vector_##type* vec, const type elem); \
- size_t (*length)(vector_##type* vec); \
- void (*resize)(vector_##type* vec, const size_t size); \
- void (*set)(vector_##type* vec, const size_t pos, type element); \
- type* (*get)(vector_##type* vec, const size_t pos); \
- void (*show)(vector_##type* vec,const char* specifier, bool debug); \
- void (*clear)(vector_##type* vec); \
- void (*delete)(vector_##type* vec); \
- }; \
- \
- void __vector_clear_##type(vector_##type* vec); \
- void __vector_push_back_##type(vector_##type* vec, type element); \
- void __vector_resize_##type(vector_##type* vec, const size_t size); \
- void __vector_show_##type(vector_##type* vec, const char* specifier, bool debug); \
- size_t __vector_length_##type(vector_##type* vec); \
- type* __vector_get_##type(vector_##type* vec, const size_t pos); \
- void __vector_set_##type(vector_##type* vec, const size_t pos, type element); \
- void __vector_delete_##type(vector_##type* vec); \
- \
- vector_##type vector_##type##_create() \
- { \
- vector_##type vec; \
- \
- vec.size_mem = 0; \
- vec.size = 0; \
- vec.array = NULL; \
- \
- vec.push_back = __vector_push_back_##type; \
- vec.length = __vector_length_##type; \
- vec.resize = __vector_resize_##type; \
- vec.get = __vector_get_##type; \
- vec.set = __vector_set_##type; \
- vec.show = __vector_show_##type; \
- vec.clear = __vector_clear_##type; \
- vec.delete = __vector_delete_##type; \
- return vec; \
- } \
- \
- void __vector_delete_##type(vector_##type* vec) \
- { \
- if (vec->array) \
- free(vec->array); \
- \
- vec->size_mem = 0; \
- vec->size = 0; \
- vec->array = NULL; \
- } \
- \
- void __vector_clear_##type(vector_##type* vec) \
- { \
- memset(vec->array, 0, sizeof(type)*(vec->size_mem)); \
- } \
- \
- void __vector_push_back_##type(vector_##type* vec, type element) \
- { \
- if (vec->size >= vec->size_mem) \
- { \
- vec->array = realloc(vec->array, sizeof(type) * (vec->size_mem + 1) * GOLDEN_RATIO); \
- is_null(vec->array); \
- memset(vec->array + vec->size_mem, 0 , ((vec->size_mem + 1) * GOLDEN_RATIO - vec->size_mem)*sizeof(type)); \
- \
- vec->size_mem = (vec->size_mem + 1) * GOLDEN_RATIO; \
- } \
- vec->array[vec->size++] = element; \
- } \
- \
- void __vector_resize_##type(vector_##type* vec, const size_t size) \
- { \
- if (size > vec->size_mem) { \
- vec->array = realloc(vec->array, sizeof(type) * (size + 1) * GOLDEN_RATIO); \
- is_null(vec->array); \
- memset(vec->array + vec->size_mem, 0 , ((size + 1) * GOLDEN_RATIO - vec->size_mem)*sizeof(type)); \
- vec->size_mem = (size + 1) * GOLDEN_RATIO; \
- } \
- vec->size = size; \
- } \
- \
- void __vector_show_##type(vector_##type* vec, const char* specifier, bool debug) \
- { \
- int i; \
- size_t n = debug? vec->size_mem : vec->size; \
- for (i = 0; i < n; i++) \
- { \
- printf(specifier,vec->array[i]); \
- } \
- printf(" \n"); \
- } \
- \
- size_t __vector_length_##type(vector_##type* vec) \
- { \
- return vec->size; \
- } \
- \
- type* __vector_get_##type(vector_##type* vec, const size_t pos) \
- { \
- if (pos < vec->size) \
- return &vec->array[pos]; \
- \
- printf("[WARNING] Vector.get() %p: is out_of_range \n",vec); \
- exit(-1); \
- return NULL; \
- } \
- \
- void __vector_set_##type(vector_##type* vec, const size_t pos, type element) \
- { \
- if (pos < vec->size) \
- { \
- vec->array[pos] = element; \
- } \
- else \
- { \
- printf("[WARNING] Vector.set() %p: is out_of_range \n",vec); \
- exit(-1); \
- } \
- }
- CREATE_VECTOR_TYPE_H(ulong);
- #define swap(a,b) __swap(&a, &b)
- void __swap(ulong* a, ulong* b)
- {
- ulong tmp = *a;
- *a = *b;
- *b = tmp;
- }
- ulong gcd (ulong a, ulong b)
- {
- while (b)
- {
- a %= b;
- swap(a, b);
- }
- return a;
- }
- int mylog(ulong value)
- {
- int pos = 0;
- while (value > 1)
- {
- pos++;
- value >>= 1;
- }
- return pos;
- }
- ulong sparse_table_query(ulong** table, size_t left, size_t right)
- {
- ulong j = mylog(right - left + 1);
- return gcd(table[left][j], table[right - (1 << j) + 1][j]);
- }
- ulong** sparse_table_build(vector_ulong* vec)
- {
- size_t m = mylog(vec->size) + 1;
- ulong** table = malloc(vec->size * sizeof(ulong*));
- size_t i;
- for (i = 0; i < vec->size; i++)
- {
- table[i] = malloc(m * sizeof(ulong));
- }
- i = 0;
- while (i < vec->size)
- {
- table[i][0] = vec->array[i];
- i++;
- }
- size_t j = 1;
- size_t pow = 2;
- while (j < m)
- {
- i = 0;
- while (i <= vec->size - pow)
- {
- table[i][j] = gcd (table[i][j - 1], table[i + (pow >> 1llu)][j - 1]);
- i++;
- }
- j++;
- pow <<= 1llu;
- }
- return table;
- }
- void sparse_table_free(ulong** table, size_t size)
- {
- size_t i;
- for (i = 0; i < size; i++)
- {
- free(table[i]);
- }
- free(table);
- }
- int main(void)
- {
- vector_ulong vec = vector_ulong_create();
- int n;
- scanf("%i", &n);
- vec.resize(&vec, n);
- int i;
- long tmp;
- for (i = 0; i < n; i++)
- {
- scanf("%lld", &tmp);
- vec.array[i] = llabs(tmp);
- }
- int count;
- scanf("%i", &count);
- ulong** table = sparse_table_build(&vec);
- size_t left;
- size_t right;
- for (i = 0; i < count; i++)
- {
- scanf("%llu %llu", &left, &right);
- printf("%llu\n", sparse_table_query(table, left, right));
- }
- sparse_table_free(table, vec.size);
- vec.delete(&vec);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement