fancy_sequence.c (4039B)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | // 1622. Fancy Sequence #include "leetcode.h" /* * write an api that generates fancy sequences using the 'append', 'addAll', and * 'multAll' operations. */ static int mod = 1e9 + 7; enum operations { op_mult, op_add }; struct list { struct list *next; int data[4]; }; struct list_op { struct list_op *next; enum operations op[4]; long val[4]; uint16_t qty_curr[4]; }; typedef struct { int qty_elem; int qty_op_elem; struct list *first; struct list *last; struct list_op *list_op_first; struct list_op *list_op_last; int last_req_val; int last_req_idx; int last_req_valid; int last_req_num; } Fancy; Fancy *fancyCreate() { Fancy *obj = (Fancy *)calloc(1, sizeof(Fancy)); return obj; } void fancyAppend(Fancy *obj, int val) { int tmp = obj->qty_elem % 4; obj->qty_elem++; if (!obj->last) { obj->last = (struct list *)calloc(1, sizeof(struct list)); obj->first = obj->last; obj->last->data[0] = val; return; } if (!tmp) { obj->last->next = (struct list *)calloc(1, sizeof(struct list)); obj->last = obj->last->next; } obj->last->data[tmp] = val; } void fancy_all(Fancy *obj, int val, enum operations op) { int tmp = obj->qty_op_elem % 4; int tmp_prev = (obj->qty_op_elem - 1) % 4; obj->last_req_val++; if (!obj->list_op_last) { obj->list_op_last = (struct list_op *)calloc(1, sizeof(struct list_op)); obj->list_op_first = obj->list_op_last; } else { if (op == obj->list_op_last->op[tmp_prev] && obj->qty_elem == obj->list_op_last->qty_curr[tmp_prev]) { if (op == op_add) obj->list_op_last->val[tmp_prev] += val; else obj->list_op_last->val[tmp_prev] *= val; if (obj->list_op_last->val[tmp_prev] >= mod) obj->list_op_last->val[tmp_prev] %= mod; return; } if (!tmp) { obj->list_op_last->next = (struct list_op *)calloc(1, sizeof(struct list_op)); obj->list_op_last = obj->list_op_last->next; } } obj->list_op_last->val[tmp] = val; obj->list_op_last->op[tmp] = op; obj->list_op_last->qty_curr[tmp] = obj->qty_elem; obj->qty_op_elem++; } void fancyAddAll(Fancy *obj, int inc) { fancy_all(obj, inc, op_add); } void fancyMultAll(Fancy *obj, int m) { fancy_all(obj, m, op_mult); } int fancyGetIndex(Fancy *obj, int idx) { struct list *list_p = obj->first; struct list_op *list_op_p = obj->list_op_first; long tmp; int idx_loc = idx / 4; if (obj->qty_elem <= idx) return -1; if (obj->last_req_idx == idx && obj->last_req_valid == obj->last_req_num && obj->qty_op_elem != 0) return obj->last_req_val; while (idx_loc-- > 0) list_p = list_p->next; tmp = list_p->data[idx % 4]; while (list_op_p) { for (int i = 0; i < 4; i++) { if (list_op_p->qty_curr[i] <= idx) continue; if (list_op_p->op[i] == op_add) tmp += list_op_p->val[i]; else tmp *= list_op_p->val[i]; if (tmp >= mod) tmp %= mod; } list_op_p = list_op_p->next; } obj->last_req_val = tmp; obj->last_req_idx = idx; obj->last_req_valid = obj->last_req_num; return (int)tmp; } void fancyFree(Fancy *obj) { struct list *list_p1 = obj->first, *list_p2; struct list_op *list_op_p1 = obj->list_op_first, *list_op_p2; while (list_p1) { list_p2 = list_p1->next; free(list_p1); list_p1 = list_p2; } while (list_op_p1) { list_op_p2 = list_op_p1->next; free(list_op_p1); list_op_p1 = list_op_p2; } free(obj); } int main() { Fancy *obj = fancyCreate(); fancyAppend(obj, 2); fancyAddAll(obj, 3); fancyAppend(obj, 7); fancyMultAll(obj, 2); int r1 = fancyGetIndex(obj, 0); printf("%d\n", r1); assert(r1 == 10); fancyAddAll(obj, 3); fancyAppend(obj, 10); fancyMultAll(obj, 2); int r2 = fancyGetIndex(obj, 0); printf("%d\n", r2); assert(r2 == 26); int r3 = fancyGetIndex(obj, 1); printf("%d\n", r3); assert(r3 == 34); int r4 = fancyGetIndex(obj, 2); printf("%d\n", r4); assert(r4 == 20); fancyFree(obj); } |