题目传送门

  传送点I

  传送点II

题目大意

  (家喻户晓的题目应该不需要大意)

  (我之前咋把NOIP 2017打成了NOIP 2018,好绝望)

Solution 1 Splay

  每行一颗Splay,没有动过的地方直接一段一个点。

  最后一列单独一颗Splay。

  暴力模拟即可。

Soluion 2 Splay II

  我们考虑倒推。对于每个询问倒推出在第一次操作前时的位置。

  考虑每个出队操作对答案的影响。

  假设询问$(x, y)$,那么最后一列横坐标大于等于$x$的位置,横坐标都会加1.

  第$x$行,纵坐标大于等于$y$的位置,纵坐标都会加1.

  然后再把这个位置塞进$(x, y)$。

  然后暴力模拟就好了。

Code

  1 /**
  2  * uoj
  3  * Problem#334
  4  * Accepted
  5  * Time: 4027ms
  6  * Memory: 25700k
  7  */
  8 #include <iostream>
  9 #include <cassert>
 10 #include <cstdlib>
 11 #include <cstdio>
 12 #ifndef WIN32
 13 #define Auto "%lld"
 14 #else
 15 #define Auto "%I64d"
 16 #endif
 17 using namespace std;
 18 typedef bool boolean;
 19 #define ll long long
 20 
 21 const int N = 3e5 + 5;
 22 
 23 typedef class SplayNode {
 24     public:
 25         int val, tg, id;
 26         SplayNode *ch[2];
 27         SplayNode *fa;
 28 
 29         SplayNode() {    }
 30 
 31         void pushDown() {
 32             for (int i = 0; i < 2; i++)
 33                 if (ch[i])
 34                     ch[i]->val += tg, ch[i]->tg += tg;
 35             tg = 0;
 36         }
 37 
 38         int which(SplayNode* p) {
 39             return p == ch[1];
 40         }
 41 }SplayNode;
 42 
 43 SplayNode pool[N << 1];
 44 SplayNode* top = pool;
 45 
 46 SplayNode* newnode(int val, int id) {
 47     top->val = val, top->id = id;
 48     top->ch[0] = top->ch[1] = top->fa = NULL;
 49     top->tg = 0;
 50     return top++;
 51 }
 52 
 53 SplayNode* stps[N];
 54 
 55 typedef class Splay {
 56     protected:
 57         void rotate(SplayNode* p) {
 58             SplayNode *fa = p->fa, *ffa = fa->fa;
 59             int df = fa->which(p);
 60             SplayNode* ls = p->ch[df ^ 1];
 61 
 62             p->fa = ffa;
 63             p->ch[df ^ 1] = fa;
 64             fa->fa = p;
 65             fa->ch[df] = ls;
 66             if (ls)
 67                 ls->fa = fa;
 68             if (ffa)
 69                 ffa->ch[ffa->which(fa)] = p;
 70         }
 71 
 72         void splay(SplayNode* p, SplayNode* fa) {
 73             SplayNode** st = stps;
 74             for (SplayNode* q = p; q; *(++st) = q, q = q->fa);
 75             for ( ; st != stps; (*st)->pushDown(), st--);
 76             for ( ; p->fa != fa; rotate(p))
 77                 if (p->fa->fa != fa)
 78                     rotate((p->fa->fa->which(p->fa) == p->fa->which(fa)) ? (p->fa) : (p));
 79             if (!fa)
 80                 rt = p;
 81         }
 82     public:
 83         SplayNode* rt;
 84 
 85         void insert(SplayNode*& p, SplayNode* fa, SplayNode* np) {
 86             if (!p) {
 87                 p = np, np->fa = fa;
 88                 return;
 89             }
 90             if (p->tg)
 91                 p->pushDown();
 92             insert(p->ch[np->val > p->val], p, np);
 93         }
 94 
 95         boolean less_bound(int x) {    // find the maximum number less than x and splay it
 96             SplayNode* ret = NULL, *p = rt, *q = NULL;
 97             while (p) {
 98                 q = p;
 99                 if (p->tg)
100                     p->pushDown();
101                 if (p->val < x)
102                     ret = p, p = p->ch[1];
103                 else
104                     p = p->ch[0];
105             }
106             if (ret)
107                 splay(ret, NULL);
108             else if (q)
109                 splay(q, NULL);
110             return ret != NULL;
111         }
112 
113         void remove(SplayNode* p) {
114             splay(p, NULL);
115             if (!p->ch[1]) {
116                 rt = p->ch[0];
117                 if (rt)
118                     rt->fa = NULL;
119                 return;
120             }
121 
122             SplayNode* q = p->ch[1];
123             while (q->ch[1])
124                 q = q->ch[1];
125             splay(q, p);
126             q->ch[0] = p->ch[0];
127             if (p->ch[0])
128                 p->ch[0]->fa = q;
129             rt = q;
130         }
131 
132         SplayNode* findMax() {
133             SplayNode* p = rt;
134             while (p && p->ch[1]) {
135                 if (p->tg)
136                     p->pushDown();
137                 p = p->ch[1];
138             }
139             if (p)
140                 splay(p, NULL);
141             return p;
142         }
143 
144         void insert(SplayNode* p) {
145             insert(rt, NULL, p);
146             splay(p, NULL);
147         }
148         
149         void getLis(SplayNode**& vs, SplayNode* p) {
150             if (!p)
151                 return;
152             if (p->tg)
153                 p->pushDown();
154             *(vs++) = p;
155             getLis(vs, p->ch[0]);
156             getLis(vs, p->ch[1]);
157         }
158 }Splay;
159 
160 int n, m, q;
161 Splay ls[N];        // maintain for (1, 1) - (n, m - 1)
162 Splay rs;
163 int xs[N], ys[N];
164 ll res[N];
165 
166 inline void init() {
167     scanf("%d%d%d", &n, &m, &q);
168     for (int i = 1; i <= q; i++)
169         scanf("%d%d", xs + i, ys + i);
170 }
171 
172 int uf[N];
173 
174 int find(int x) {
175     return (uf[x] == x) ? (x) : (uf[x] = find(uf[x])); 
176 }
177 
178 inline void solve() {
179     for (int i = 1; i <= q; i++)
180         uf[i] = i;
181 
182     SplayNode *p;
183     for (int i = q; i; i--) {
184         int x = xs[i], y = ys[i];
185         while ((p = rs.findMax()) && p->val == n)
186             uf[find(p->id)] = i, rs.remove(p);
187         if (rs.rt) {
188             if (rs.less_bound(x)) {
189                 p = rs.rt->ch[1];
190                 if (p)
191                     p->val++, p->tg++;
192             } else
193                 rs.rt->val++, rs.rt->tg++;
194         }
195         if (y == m) {
196             rs.insert(newnode(x, i));
197         } else {
198             Splay& sp = ls[x];
199             if (sp.rt) {
200                 if (sp.less_bound(y)) {
201                     p = sp.rt->ch[1];
202                     if (p)
203                         p->val++, p->tg++;
204                 } else
205                     sp.rt->val++, sp.rt->tg++;
206             }
207             while ((p = sp.findMax()) && p->val == m)
208                 rs.insert(newnode(x, p->id)), sp.remove(p);
209             sp.insert(newnode(y, i));
210         }
211     }
212 
213     SplayNode **pp, **pq;
214     for (int i = 1; i <= n; i++) {
215         pp = stps;
216         ls[i].getLis(pp, ls[i].rt);
217         for (pq = stps; pq != pp; pq++)
218             res[(*pq)->id] = (i - 1) * 1ll * m + (*pq)->val;
219     }
220     pp = stps;
221     rs.getLis(pp, rs.rt);
222     for (pq = stps; pq != pp; pq++)
223         res[(*pq)->id] = (*pq)->val * 1ll * m;
224     for (int i = 1; i <= q; i++)
225         printf(Auto"\n", res[find(i)]);
226 }
227 
228 int main() {
229     init();
230     solve();
231     return 0;
232 }
Splay

相关文章: