zoukankan      html  css  js  c++  java
  • 4825: [Hnoi2017]单旋

    4825: [Hnoi2017]单旋

    链接

    分析:

      以后采取更保险的方式写代码!!!81行本来以为不特判也可以,然后就总是比答案大1,甚至出现负数,调啊调啊调啊调~~~

      只会旋转最大值和最小值,以最小值为例,画一下图可以看出,旋转后,深度分成三部分讨论,最小值的深度(变为1),最小值右子树的深度(不变),其他的点的深度(整体加1)。所以线段树维护一下。

      现在考虑如何插入一个点,可以知道一个点加入后一定是在前驱的右边,或者后继的左边。一个性质:前驱后继一定在splay上是一个是另一个的祖先的关系(反证:若中间存在一个点为它们两个的祖先,那么这个点前驱后继一定有一个是中间的点,没有重复的数字)。那么这个点加入的过程中,一定是加入在前驱后继中比较深的一个点。所以可以直接找到前驱后继,深度大的就是它的父节点。

      找到根据splay的性质找到相应的区间,进行区间加减,单点求值。前驱后继可以直接在线段树上二分,或者直接用set。(或者直接splay)

    代码:

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<cmath>
      6 #include<cctype>
      7 #include<set>
      8 #include<queue>
      9 #include<vector>
     10 #include<map>
     11 #define Root 1, tot, 1
     12 #define lson l, mid, rt << 1
     13 #define rson mid + 1, r, rt << 1 | 1
     14 #define Clear(x) ch[x][0] = ch[x][1] = fa[x] = 0 
     15 using namespace std;
     16 typedef long long LL;
     17 
     18 inline int read() {
     19     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
     20     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
     21 }
     22 
     23 const int N = 100005;
     24 
     25 int T[N << 2], tag[N << 2], ch[N][2], fa[N], a[N], disc[N], opt[N], Rt;
     26 set<int> s;
     27 set<int> :: iterator it;
     28 
     29 void pushdown(int rt) {
     30     tag[rt << 1] += tag[rt]; tag[rt << 1 | 1] += tag[rt];
     31     T[rt << 1] += tag[rt], T[rt << 1 | 1] += tag[rt];
     32     tag[rt] = 0;
     33 }
     34 void update(int l,int r,int rt,int L,int R,int v) {
     35     if (L <= l && r <= R) {
     36         tag[rt] += v; T[rt] += v; return; 
     37     }
     38     if (tag[rt]) pushdown(rt);
     39     int mid = (l + r) >> 1;
     40     if (L <= mid) update(lson, L, R, v);
     41     if (R > mid) update(rson, L, R, v);
     42 }
     43 void Change(int l,int r,int rt,int p,int v) {
     44     if (l == r) { T[rt] = v, tag[rt] = 0; return ; }
     45     if (tag[rt]) pushdown(rt);
     46     int mid = (l + r) >> 1;
     47     if (p <= mid) Change(lson, p, v);
     48     if (p > mid) Change(rson, p, v);
     49 }
     50 int query(int l,int r,int rt,int p) {
     51     if (l == r) return T[rt];
     52     if (tag[rt]) pushdown(rt);
     53     int mid = (l + r) >> 1;
     54     if (p <= mid) return query(lson, p);
     55     if (p > mid) return query(rson, p);
     56 }
     57 int main() {
     58     int n = read(), tot = 0;
     59     for (int i = 1; i <= n; ++i) {
     60         opt[i] = read();
     61         if (opt[i] == 1) a[i] = read(), disc[++tot] = a[i];
     62     }
     63     s.insert(-1e9), s.insert(1e9);
     64     sort(disc + 1,disc + tot + 1);
     65     for (int i = 1; i <= n; ++i) if (opt[i] == 1) a[i] = lower_bound(disc + 1, disc + tot + 1, a[i]) - disc;
     66     
     67     for (int pre, suc, now, mx, mn, i = 1; i <= n; ++i) {
     68         if (opt[i] == 1) {
     69             it = s.lower_bound(a[i]); suc = *it; pre = *(--it); now = 1;
     70             int d1 = -1, d2 = -1;
     71             if (pre != -1e9) d1 = query(Root, pre);
     72             if (suc != 1e9) d2 = query(Root, suc);
     73             if (d1 > d2) now = d1 + 1, fa[a[i]] = pre, ch[pre][1] = a[i];
     74             if (d1 < d2) now = d2 + 1, fa[a[i]] = suc, ch[suc][0] = a[i];
     75             if (now == 1) Rt = a[i], Clear(Rt);
     76             Change(Root, a[i], now);
     77             s.insert(a[i]);
     78         }
     79         else if (opt[i] & 1) {
     80             it = s.end(); it --; it --; mx = *it; now = query(Root, mx); 
     81             if (mx != Rt) { // 注意!!!此处需特判!!!!!!!!!!!!! 
     82                 update(Root, 1, mx - 1, 1);
     83                 if (fa[mx] + 1 <= mx - 1) {
     84                     update(Root, fa[mx] + 1, mx - 1, -1);
     85                 }
     86                 fa[ch[mx][0]] = fa[mx]; ch[fa[mx]][1] = ch[mx][0];
     87                 ch[mx][0] = Rt; fa[Rt] = mx; Rt = mx; fa[mx] = 0;
     88                 Change(Root, mx, 1);
     89             }
     90             if (opt[i] == 5) {
     91                 Rt = ch[mx][0], fa[Rt] = 0; Clear(mx);
     92                 s.erase(s.find(mx)); 
     93                 update(Root, 1, tot, -1);
     94             }
     95         }
     96         else {
     97             it = s.begin(); it ++; mn = *it; now = query(Root, mn);
     98             if (mn != Rt) {
     99                 update(Root, mn + 1, tot, 1);
    100                 if (mn + 1 <= fa[mn] - 1) {
    101                     update(Root, mn + 1, fa[mn] - 1, -1);
    102                 } 
    103                 fa[ch[mn][1]] = fa[mn]; ch[fa[mn]][0] = ch[mn][1];
    104                 ch[mn][1] = Rt; fa[Rt] = mn; Rt = mn; fa[mn] = 0;
    105                 Change(Root, mn, 1); 
    106             }
    107             if (opt[i] == 4) {
    108                 Rt = ch[mn][1]; fa[Rt] = 0; Clear(mn);
    109                 s.erase(s.find(mn));
    110                 update(Root, 1, tot, -1);
    111             }
    112         }
    113         printf("%d
    ",now);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    pycharm连接mysql报错!Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' prope
    Django之视图
    Django模板语言相关内容
    Django使用ORM之多对多(四)
    Django使用ORM之一对多(三)
    018_序列化模块_什么是模块
    017_os_sys_time_collection_random 模块
    015_内置函数2
    014_内置函数
    013_生成器(yield)_列表推导式
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10116828.html
Copyright © 2011-2022 走看看