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 }

 

posted @ 2017-02-20 19:23  ichneumon  阅读(191)  评论(0编辑  收藏  举报