之前写线段树套splay数组版。。写了6.2k。。然后弃疗了。现在发现还是很水的。。嘎嘎。。
zju过不了,超时。
upd:才发现zju是多组数据。。TLE一版才发现。然后改了,MLE。。。手写内存池。。尼玛终于过了。。附zju2112代码于后。
bzoj倒是过了,1A的感觉还是很爽的。。可是时间不好看。。这就是所谓(O(nlog^3n))的复杂度的可怜之处么?
写挂的地方:
- insert一定要是传地址指针进去。
- delete时先把地址指针delete掉,最后把是地址指针指向左儿子or右儿子or NULL。
- 节点初始化时一定要把左右儿子指针指向NULL。
- 注意脑残,b打错变量名的问题。
做法:线段树约束区间,平衡树支持修改和查询,没了。
修改:每次在包含点的线段树节点所包含的平衡树中删除要改的节点值,在插入新的值,(O(log^2n))。
查询:由于无法直接查询,所以二分答案,求得答案在区间內的排名,等于各区间小于该值的节点数量,select直接搞,总共(O(log^3n)),具体可以先插入一个值节点,在求值节点的rank,最后删掉即可。
我是用线段树套treap。
然后树状数组套平衡树也可以过,常数小很多。。。
达成成就:AC树套树。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <ctime> 4 #include <cstring> 5 typedef long long LL; 6 const int maxn = 10000 + 20; 7 int n, m, sum, a[maxn], INF = 0x3f3f3f3f; 8 struct treap_node { 9 treap_node *ch[2]; 10 int key, fix, cnt, size; 11 treap_node() { 12 ch[0] = ch[1] = NULL; 13 } 14 treap_node(int _key) { 15 ch[0] = ch[1] = NULL; 16 key = _key; 17 size = cnt = 1; 18 fix = rand(); 19 } 20 } *T[maxn << 2]; 21 inline void maintain(treap_node *t) { 22 t->size = t->cnt; 23 if(t->ch[0]) t->size += t->ch[0]->size; 24 if(t->ch[1]) t->size += t->ch[1]->size; 25 } 26 void rot(treap_node *&t, int d) { 27 treap_node *p = t->ch[d ^ 1]; 28 t->ch[d ^ 1] = p->ch[d], p->ch[d] = t; 29 maintain(t), maintain(p); 30 t = p; 31 } 32 void insert(treap_node *&t, int val) { 33 if(t == NULL) { 34 t = new treap_node(val); 35 } else { 36 if(val < t->key) { 37 insert(t->ch[0], val); 38 if(t->ch[0]->fix < t->fix) rot(t, 1); 39 } else if(t->key < val) { 40 insert(t->ch[1], val); 41 if(t->ch[1]->fix < t->fix) rot(t, 0); 42 } else 43 ++t->cnt; 44 } 45 maintain(t); 46 } 47 void del(treap_node *&t, int val) { 48 if(t->key == val) { 49 if(t->cnt == 1) { 50 if(!t->ch[0] || !t->ch[1]) { 51 treap_node *p = t; 52 if(!p->ch[0]) p = t->ch[1]; 53 else p = t->ch[0]; 54 delete t; 55 t = p; 56 } else { 57 int d = t->ch[0]->fix < t->ch[1]->fix; 58 rot(t, d); 59 del(t->ch[d], val); 60 } 61 } else --t->cnt; 62 } else del(t->ch[t->key < val], val); 63 if(t) maintain(t); 64 } 65 int select(treap_node *t, int val) { 66 if(t == NULL) return 0; 67 if(val < t->key) return select(t->ch[0], val); 68 int p = (t->ch[0]) ? t->ch[0]->size + t->cnt : t->cnt; 69 if(t->key < val) p += select(t->ch[1], val); 70 return p; 71 } 72 bool ok; 73 void query(int l, int r, int rt, int ql, int qr, int val) { 74 if(ql <= l && r <= qr) { 75 sum += select(T[rt], val); 76 return ; 77 } else { 78 int mid = (l + r) >> 1; 79 if(ql <= mid) query(l, mid, rt << 1, ql, qr, val); 80 if(mid < qr) query(mid + 1, r, rt << 1 | 1, ql, qr, val); 81 } 82 } 83 void seg_del(int l, int r, int rt, int pos, int val) { 84 del(T[rt], val); 85 if(l == r) return ; 86 int mid = (l + r) >> 1; 87 if(pos <= mid) seg_del(l, mid, rt << 1, pos, val); 88 else if(mid < pos) seg_del(mid + 1, r, rt << 1 | 1, pos, val); 89 } 90 void seg_insert(int l, int r, int rt, int pos, int val) { 91 insert(T[rt], val); 92 if(l == r) return ; 93 int mid = (l + r) >> 1; 94 if(pos <= mid) seg_insert(l, mid, rt << 1, pos, val); 95 else if(mid < pos) seg_insert(mid + 1, r, rt << 1 | 1, pos, val); 96 } 97 98 char gchar() { 99 char ret = getchar(); 100 for(; ret == ' ' || ret == ' ' || ret == ' '; ret = getchar()); 101 return ret; 102 } 103 int main() { 104 #ifndef ONLINE_JUDGE 105 freopen("data.in", "r", stdin), freopen("data.out", "w", stdout); 106 #endif 107 scanf("%d%d", &n, &m); 108 srand(n * m + 258); 109 for(int i = 1; i <= n; ++i) { 110 scanf("%d", &a[i]); 111 seg_insert(1, n, 1, i, a[i]); 112 } 113 ok = false; 114 for(int i = 1, p, b, c, d; i <= m; ++i) { 115 d = gchar(); 116 if(d == 'C') { 117 scanf("%d%d", &p, &b); 118 seg_del(1, n, 1, p, a[p]); 119 a[p] = b; 120 seg_insert(1, n, 1, p, a[p]); 121 } else { 122 scanf("%d%d%d", &b, &c, &p); 123 LL l = 0, r = INF; 124 while(l < r) { 125 LL mid = (l + r) >> 1; 126 sum = 0; 127 query(1, n, 1, b, c, mid); 128 if(sum < p) { 129 l = mid + 1; 130 } else { 131 r = mid; 132 } 133 } 134 printf("%lld ", l); 135 } 136 } 137 return 0; 138 }
1 #include <cstdio> 2 #include <cstdlib> 3 #include <ctime> 4 #include <cstring> 5 typedef long long LL; 6 const int maxn = 50000 + 1; 7 int n, m, sum, a[maxn], INF = 0x3f3f3f3f; 8 struct treap_node { 9 treap_node *ch[2]; 10 int key, fix, cnt, size; 11 treap_node() { 12 ch[0] = ch[1] = NULL; 13 } 14 treap_node(int _key) { 15 ch[0] = ch[1] = NULL; 16 key = _key; 17 size = cnt = 1; 18 fix = rand(); 19 } 20 } *T[maxn << 2]; 21 treap_node null_thing; 22 struct storage { 23 treap_node free_node[maxn * 18]; 24 int top, rec; 25 void init() { 26 rec = maxn * 18; 27 for(int i = 0; i < rec; ++i) free_node[top++] = i; 28 } 29 treap_node _new(int val) { 30 return free_node[--top] = treap_node(val); 31 } 32 void back_data() { 33 for(int i = top; i < rec; ++i) free_node[top++] = i; 34 } 35 }S; 36 37 inline void maintain(treap_node *t) { 38 t->size = t->cnt; 39 if(t->ch[0]) t->size += t->ch[0]->size; 40 if(t->ch[1]) t->size += t->ch[1]->size; 41 } 42 void rot(treap_node *&t, int d) { 43 treap_node *p = t->ch[d ^ 1]; 44 t->ch[d ^ 1] = p->ch[d], p->ch[d] = t; 45 maintain(t), maintain(p); 46 t = p; 47 } 48 void insert(treap_node *&t, int val) { 49 if(t == NULL) { 50 S._new(val); 51 t = &S.free_node[S.top]; 52 } else { 53 if(val < t->key) { 54 insert(t->ch[0], val); 55 if(t->ch[0]->fix < t->fix) rot(t, 1); 56 } else if(t->key < val) { 57 insert(t->ch[1], val); 58 if(t->ch[1]->fix < t->fix) rot(t, 0); 59 } else 60 ++t->cnt; 61 } 62 maintain(t); 63 } 64 void del(treap_node *&t, int val) { 65 if(t->key == val) { 66 if(t->cnt == 1) { 67 if(!t->ch[0] || !t->ch[1]) { 68 treap_node *p = t; 69 if(!p->ch[0]) p = t->ch[1]; 70 else p = t->ch[0]; 71 t = p; 72 } else { 73 int d = t->ch[0]->fix < t->ch[1]->fix; 74 rot(t, d); 75 del(t->ch[d], val); 76 } 77 } else --t->cnt; 78 } else del(t->ch[t->key < val], val); 79 if(t) maintain(t); 80 } 81 int select(treap_node *t, int val) { 82 if(t == NULL) return 0; 83 if(val < t->key) return select(t->ch[0], val); 84 int p = (t->ch[0]) ? t->ch[0]->size + t->cnt : t->cnt; 85 if(t->key < val) p += select(t->ch[1], val); 86 return p; 87 } 88 bool ok; 89 void query(int l, int r, int rt, int ql, int qr, int val) { 90 if(ql <= l && r <= qr) { 91 sum += select(T[rt], val); 92 return ; 93 } else { 94 int mid = (l + r) >> 1; 95 if(ql <= mid) query(l, mid, rt << 1, ql, qr, val); 96 if(mid < qr) query(mid + 1, r, rt << 1 | 1, ql, qr, val); 97 } 98 } 99 void seg_del(int l, int r, int rt, int pos, int val) { 100 del(T[rt], val); 101 if(l == r) return ; 102 int mid = (l + r) >> 1; 103 if(pos <= mid) seg_del(l, mid, rt << 1, pos, val); 104 else if(mid < pos) seg_del(mid + 1, r, rt << 1 | 1, pos, val); 105 } 106 void seg_insert(int l, int r, int rt, int pos, int val) { 107 insert(T[rt], val); 108 if(l == r) return ; 109 int mid = (l + r) >> 1; 110 if(pos <= mid) seg_insert(l, mid, rt << 1, pos, val); 111 else if(mid < pos) seg_insert(mid + 1, r, rt << 1 | 1, pos, val); 112 } 113 114 char gchar() { 115 char ret = getchar(); 116 for(; ret == ' ' || ret == ' ' || ret == ' '; ret = getchar()); 117 return ret; 118 } 119 void del_tree(int l, int r, int rt) { 120 T[rt] = NULL; 121 if(l == r) return ; 122 int mid = (l + r) >> 1; 123 del_tree(l, mid, rt << 1); 124 del_tree(mid + 1, r, rt << 1 | 1); 125 } 126 int main() { 127 128 int test_num; 129 scanf("%d", &test_num); 130 S.init(); 131 while(test_num--) { 132 S.back_data(); 133 scanf("%d%d", &n, &m); 134 del_tree(1, n, 1); 135 srand(n * m + 258); 136 for(int i = 1; i <= n; ++i) { 137 scanf("%d", &a[i]); 138 seg_insert(1, n, 1, i, a[i]); 139 } 140 ok = false; 141 for(int i = 1, p, b, c, d; i <= m; ++i) { 142 d = gchar(); 143 if(d == 'C') { 144 scanf("%d%d", &p, &b); 145 seg_del(1, n, 1, p, a[p]); 146 a[p] = b; 147 seg_insert(1, n, 1, p, a[p]); 148 } else { 149 scanf("%d%d%d", &b, &c, &p); 150 LL l = 0, r = INF; 151 while(l < r) { 152 LL mid = (l + r) >> 1; 153 sum = 0; 154 query(1, n, 1, b, c, mid); 155 if(sum < p) { 156 l = mid + 1; 157 } else { 158 r = mid; 159 } 160 } 161 printf("%lld ", l); 162 } 163 } 164 } 165 return 0; 166 }