#include #include #include #include #include #include typedef struct Pair { int fst; int snd; } Key; typedef struct { Key key; void* value; } data; bool comp_greater(Key a, Key b) { return a.fst == b.fst ? a.snd > b.snd : a.fst > b.fst; } bool comp_gt(Key a, Key b) { return a.fst == b.fst ? a.snd >= b.snd : a.fst >= b.fst; } bool comp_less(Key a, Key b) { return a.fst == b.fst ? a.snd < b.snd : a.fst < b.fst; } bool comp_lt(Key a, Key b) { return a.fst == b.fst ? a.snd <= b.snd : a.fst <= b.fst; } bool comp_equal(Key a, Key b) { return a.fst == b.fst && a.snd == b.snd; } typedef struct FibonacciNode FNode; struct FibonacciNode { FNode* left; FNode* right; FNode* parent; FNode* child; Key key; void* value; bool mark; int degree; }; typedef FNode FHeap; typedef FNode FElem; FNode* init_fnode(Key key, void* value) { FNode* new_node = (FNode *)malloc(sizeof(FNode)); new_node->left = new_node->right = new_node; new_node->parent = NULL; new_node->child = NULL; new_node->key = key; new_node->value = value; new_node->mark = false; new_node->degree = 0; return new_node; } void free_fnode(FNode* to_free) { to_free->degree = -1; free(to_free); } void kill_fnode(FNode* to_kill) { FNode* kid = to_kill->child; if (kid) { kid->left->right = NULL; while (kid->right != NULL) { kid = kid->right; kill_fnode(kid->left); } kill_fnode(kid); } free_fnode(to_kill); } void add_fnode(FNode* old, FNode* new_right) { FNode* old_right = old->right; assert(old != new_right); assert(old_right != new_right); old->right = new_right; old_right->left = new_right; new_right->left = old; new_right->right = old_right; } FHeap* init_fheap(void) { return NULL; } FElem* add_fheap(FHeap** H, FNode* new_node) { assert(H); assert(new_node); FNode* old_node = *H; new_node->parent = NULL; new_node->mark = false; if (old_node) { add_fnode(old_node, new_node); if (comp_greater(old_node->key, new_node->key)) *H = new_node; } else { new_node->left = new_node; new_node->right = new_node; *H = new_node; } return new_node; } FElem* push_fheap(FHeap** H, Key key, void* value) { FNode* new_node = init_fnode(key, value); return add_fheap(H, new_node); } bool is_empty_fheap(FHeap* H) { return H == NULL; } data min_fheap(FHeap* H) { assert(H); data d; FNode* head = H; d.key = head->key; d.value = head->value; return d; } data elem_data_fheap(FElem* x) { assert(x); data d; d.key = x->key; d.value = x->value; return d; } void remove_from_fheap(FHeap** H, FNode* x) { assert(!x->parent); if (x->right == x) *H = NULL; else { x->left->right = x->right; x->right->left = x->left; *H = x->right; } x->left = x; x->right = x; x->parent = NULL; } FHeap* union_fheap(FHeap* H1, FHeap* H2) { if (!H1) return H2; if (!H2) return H1; if (comp_less(min_fheap(H2).key, min_fheap(H1).key)) return union_fheap(H2, H1); FNode* H1first = H1; FNode* H1last = H1first->left; FNode* H2first = H2; FNode* H2last = H2first->left; H1last->right = H2first; H2first->left = H1last; H2last->right = H1first; H1first->left = H2last; return H1first; } FNode* link_fheap(FHeap** H, FNode* x, FNode* y) { assert(x); assert(y); assert(x->degree == y->degree); if (comp_greater(x->key, y->key)) return link_fheap(H, y, x); remove_from_fheap(H, y); if (x->child) { FNode* z = x->child; y->right = z; y->left = z->left; z->left->right = y; z->left = y; } y->parent = x; x->child = y; x->degree++; y->mark = false; return x; } void match_degrees_fheap(FHeap** H, FNode** A, FNode* x) { int d = x->degree; while (A[d]) { if (d > 99) exit(1); FNode* y = A[d]; if (y != x) { x = link_fheap(H, x, y); A[d] = NULL; d++; } else break; } A[d] = x; } void consolidate_fheap(FHeap** H) { FNode* x = *H; if (!x) return; FNode** A = (FNode**)calloc(100, sizeof(FNode)); memset(A, '\0', 100); assert(x->degree >= 0); FNode* last = x->left; while(x != last) { FNode* next = x->right; match_degrees_fheap(H, A, x); x = next; } match_degrees_fheap(H, A, last); *H = init_fheap(); for (int i = 0; i < 100; i++) if (A[i]) add_fheap(H, A[i]); free(A); } data pop_fheap(FHeap** H) { assert(H && *H); FNode* z = *H; data d = elem_data_fheap(z); FNode* first = z->child; remove_from_fheap(H, z); free_fnode(z); if (first) { FNode* current = first->right; while (current != first) { current->parent = NULL; current = current->right; } first->parent = NULL; *H = union_fheap(*H, first); } consolidate_fheap(H); return d; } void decrease_key_fheap(FHeap** H, FElem* x, Key new_key) { assert(H && *H); assert(x && comp_gt(x->key, new_key)); x->key = new_key; if (x->parent && comp_greater(x->parent->key, new_key)) { if (x->left == x) { assert(x->parent->degree == 2); x->parent->child = NULL; } else { assert(x->parent->degree > 2); x->left->right = x->right; x->right->left = x->left; x->parent->child = x->left; } x->parent->degree--; add_fheap(H, x); if (! x->parent->mark) { x->parent->mark = true; } else decrease_key_fheap(H, x->parent, x->parent->key); } else { if (comp_less(new_key, (*H)->key)) { assert(!x->parent); *H = x; } } } void delete_fheap(FHeap** H, FElem* x) { decrease_key_fheap(H, x, (Key){INT_MIN, INT_MIN}); pop_fheap(H); } void free_fheap(FHeap** H) { FNode* header = *H; FNode* first = header; if (header) { while(header != first) { FNode* next = header->right; kill_fnode(header); header = next; } } *H = NULL; } int main(void) { int N; scanf("%d", &N); int* A = (int *)calloc(N, sizeof(int)); int* B = (int *)calloc(2 * N, sizeof(int)); if (A == NULL || B == NULL) exit(EXIT_FAILURE); for (int i = 0; i < N; i++) scanf("%d", &A[i]); for (int i = 0; i < N; i++) { scanf("%d", &B[i]); B[i + N] = B[i]; } int m = 1073741824; for (int i = 0; i < N; i++) { FHeap* pq = init_fheap(); for (int j = 0; j < N; j++) push_fheap(&pq, (Key){A[j], 0}, NULL); for (int j = 0; j < N; j++) { data x = pop_fheap(&pq); Key a = x.key; push_fheap(&pq, (Key){a.fst + B[i + j] / 2, a.snd + 1}, NULL); } int tmp = 0; while (!is_empty_fheap(pq)) { data x = pop_fheap(&pq); Key a = x.key; tmp = tmp > a.snd ? tmp : a.snd; } m = m < tmp ? m : tmp; free_fheap(&pq); } printf("%d\n", m); free(A); free(B); return 0; }