BZOJ4552: [Tjoi2016&Heoi2016]排序
题目大意
给你一个$n$的排列,要求支持$m$次把$(l_i,r_i)$区间内数字升序或降序排,最后求某一个位置上的值。
简要题解
一开始维护$n$棵权值线段树,然后你需要支持split一棵线段树或者merge一棵线段树,用平衡树来维护区间就好了。
关于线段树合并的复杂度分析。split复杂度显然和求第k大是一致的,而merge操作每次遍历到两个点都会删去一个,反正每次插入$\log n$个节点,你删的点数总不会超过插入的点数啊。
果然认真写然后认真思考然后肉眼查错效果要好很多,大概写完也没怎么调试,把空间开到$1e7$在食堂吃饭的时候随手交了一发然后和老高谈笑风生中AC了233.
似乎跑的挺快(Rank5~)?
还有就是,我线段树换写法了,感觉这种写法蛮好玩的,直接把merge和split写成节点类的成员函数,以前是数组党233
1 //write by HuZhifeng(id : ichn(eumon) or sbit) @ 2017-02-20 周一 10:52 上午 2 // It attains sublime 3 // a-----------n----------d 4 // yet performs common task. 5 #include <bits/stdc++.h> 6 using namespace std; 7 namespace my_header { 8 #define pb push_back 9 #define mp make_pair 10 #define pir pair<int, int> 11 #define vec vector<int> 12 #define pc putchar 13 #define clr(t) memset(t, 0, sizeof t) 14 #define pse(t, v) memset(t, v, sizeof t) 15 #define bl puts("") 16 #define wn(x) wr(x), bl 17 #define ws(x) wr(x), pc(' ') 18 const int INF = 0x3f3f3f3f; 19 typedef long long LL; 20 typedef double DB; 21 inline char gchar() { 22 char ret = getchar(); 23 for(; (ret == '\n' || ret == '\r' || ret == ' ') && ret != EOF; ret = getchar()); 24 return ret; } 25 template<class T> inline void fr(T &ret, char c = ' ', int flg = 1) { 26 for(c = getchar(); (c < '0' || '9' < c) && c != '-'; c = getchar()); 27 if (c == '-') { flg = -1; c = getchar(); } 28 for(ret = 0; '0' <= c && c <= '9'; c = getchar()) 29 ret = ret * 10 + c - '0'; 30 ret = ret * flg; } 31 inline int fr() { int t; fr(t); return t; } 32 template<class T> inline void fr(T&a, T&b) { fr(a), fr(b); } 33 template<class T> inline void fr(T&a, T&b, T&c) { fr(a), fr(b), fr(c); } 34 template<class T> inline char wr(T a, int b = 10, bool p = 1) { 35 return a < 0 ? pc('-'), wr(-a, b, 0) : (a == 0 ? (p ? pc('0') : p) : 36 (wr(a/b, b, 0), pc('0' + a % b))); 37 } 38 template<class T> inline void wt(T a) { wn(a); } 39 template<class T> inline void wt(T a, T b) { ws(a), wn(b); } 40 template<class T> inline void wt(T a, T b, T c) { ws(a), ws(b), wn(c); } 41 template<class T> inline void wt(T a, T b, T c, T d) { ws(a), ws(b), ws(c), wn(d); } 42 template<class T> inline T gcd(T a, T b) { 43 return b == 0 ? a : gcd(b, a % b); } 44 template<class T> inline T fpw(T b, T i, T _m, T r = 1) { 45 for(; i; i >>= 1, b = b * b % _m) 46 if(i & 1) r = r * b % _m; 47 return r; } 48 }; 49 using namespace my_header; 50 51 52 const int MAXN = 1e7 + 100; 53 #define SN SegNode 54 #define lc ch[0] 55 #define rc ch[1] 56 struct SegNode { 57 SegNode *ch[2]; 58 int s; 59 void update() { 60 s = (lc ? lc->s : 0) + (rc ? rc->s : 0); 61 } 62 int kth(int l, int r, int k) { 63 if (l == r) 64 return l; 65 int m = (l + r) >> 1; 66 int ls = lc ? lc->s : 0; 67 if (k <= ls) 68 return lc->kth(l, m, k); 69 return rc->kth(m + 1, r, k - ls); 70 } 71 void insert(int, int, int); 72 pair<SegNode*, SegNode*> split(int, int, int); 73 SegNode* merge(int, int, SegNode*); 74 } node_pool[MAXN], *loc = node_pool; 75 SegNode* newSegNode() { 76 return loc++; 77 } 78 79 pair<SegNode*, SegNode*> SegNode::split(int l, int r, int k) { 80 if (k == 0) 81 return make_pair((SegNode*)NULL, this); 82 if (l == r || k == this->s) 83 return make_pair(this, (SegNode*)NULL); 84 int m = (l + r) >> 1; 85 int ls = lc ? lc->s : 0; 86 if (k <= ls) { 87 pair<SegNode*, SegNode*> res = lc->split(l, m, k); 88 SegNode* nr = newSegNode(); 89 nr->lc = res.first; 90 nr->rc = NULL; 91 nr->update(); 92 this->lc = res.second; 93 this->update(); 94 return make_pair(nr, this); 95 } else { 96 pair<SegNode*, SegNode*> res = rc->split(m + 1, r, k - ls); 97 this->rc = res.first; 98 this->update(); 99 SegNode* nr = newSegNode(); 100 nr->lc = NULL; 101 nr->rc = res.second; 102 nr->update(); 103 return make_pair(this, nr); 104 } 105 } 106 107 SegNode* SegNode::merge(int l, int r, SegNode* x) { 108 if (l != r && x != NULL) { 109 int m = (l + r) >> 1; 110 if (!this->lc) 111 this->lc = x->lc; 112 else { 113 if (x->lc) 114 this->lc->merge(l, m, x->lc); 115 } 116 if (!this->rc) 117 this->rc = x->rc; 118 else { 119 if (x->rc) 120 this->rc->merge(m + 1, r, x->rc); 121 } 122 this->update(); 123 } 124 return this; 125 } 126 127 set<pair<int, pair<int, int> > > status; 128 set<pair<int, pair<int, int> > >::iterator tmp, tmp2; 129 pair<int, pair<int, int> > rec; 130 SegNode* root[MAXN]; 131 132 void SegNode::insert(int l, int r, int v) { 133 if (l == r) 134 s = 1; 135 else { 136 int m = (l + r) >> 1; 137 if (v <= m) { 138 if (!this->lc) 139 this->lc = newSegNode(); 140 this->lc->insert(l, m, v); 141 } else { 142 if (!this->rc) 143 this->rc = newSegNode(); 144 this->rc->insert(m + 1, r, v); 145 } 146 this->update(); 147 } 148 } 149 150 int n, m; 151 // 沉下心来 细节是魔鬼 通过思考 战胜魔鬼! 152 void split(int p, int tp) { 153 pair<SegNode*, SegNode*> res; 154 tmp = status.upper_bound(make_pair(p, make_pair(0, 0))); 155 if (tmp != status.begin() && tmp->first != p) 156 --tmp; 157 SegNode* nr = newSegNode(); 158 if (tmp->second.second == 0) { 159 res = root[tmp->first]->split(1, n, p - tmp->first + tp); 160 root[tmp->first] = res.first; 161 nr->merge(1, n, res.second); 162 } else { 163 res = root[tmp->first]->split(1, n, tmp->second.first - p + tmp->first - tp); 164 root[tmp->first] = res.second; 165 nr->merge(1, n, res.first); 166 } 167 rec = *tmp; 168 status.erase(tmp); 169 if (root[rec.first]) 170 status.insert(make_pair(rec.first, make_pair(root[rec.first]->s, rec.second.second))); 171 if (nr) { 172 rec = *status.insert(make_pair(p + tp, make_pair(nr->s, rec.second.second))).first; 173 if (rec.second.first == 0) { 174 status.erase(rec); 175 } else { 176 root[rec.first] = nr; 177 } 178 } 179 } 180 181 int main() { 182 #ifdef lol 183 freopen("4552.in", "r", stdin); 184 freopen("4552.out", "w", stdout); 185 #endif 186 187 fr(n, m); 188 for (int i = 1; i <= n; ++i) { 189 root[i] = newSegNode(); 190 root[i]->insert(1, n, fr()); 191 status.insert(make_pair(i, make_pair(1, 0))); 192 } 193 while (m--) { 194 int op, l, r; 195 fr(op, l, r); 196 //for (auto &&i : status) { 197 // wt(i.first, i.second.first, i.second.second); 198 //} 199 //puts(""); 200 split(l, 0); 201 split(r, 1); 202 //for (auto &&i : status) { 203 // wt(i.first, i.second.first, i.second.second); 204 //} 205 //puts(""); 206 tmp2 = tmp = status.lower_bound(make_pair(l, make_pair(0, 0))); 207 for (++tmp2; tmp2 != status.end() && tmp2->first <= r; ++tmp2) { 208 root[l]->merge(1, n, root[tmp2->first]); 209 root[tmp2->first] = NULL; 210 } 211 rec = *tmp; 212 status.erase(tmp, tmp2); 213 status.insert(make_pair(rec.first, make_pair(root[l]->s, op))); 214 } 215 //for (auto &&i : status) { 216 // wt(i.first, i.second.first, i.second.second); 217 // } 218 // puts(""); 219 // 220 fr(m); 221 tmp = status.upper_bound(make_pair(m, make_pair(0, 0))); 222 if (tmp != status.begin() && tmp->first != m) 223 --tmp; 224 m -= tmp->first; 225 wt(root[tmp->first]->kth(1, n, tmp->second.second ? tmp->second.first - m : (m + 1))); 226 227 return 0; 228 }