• BZOJ3196 二逼平衡树


    3196: Tyvj 1730 二逼平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB

    Description

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
    1.查询k在区间内的排名
    2.查询区间内排名为k的值
    3.修改某一位值上的数值
    4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
    5.查询k在区间内的后继(后继定义为大于x,且最小的数)

    Input

    第一行两个数 n,m 表示长度为n的有序序列和m个操作
    第二行有n个数,表示有序序列
    下面有m行,opt表示操作标号
    若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
    若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
    若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
    若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
    若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继

    Output

    对于操作1,2,4,5各输出一行,表示查询结果

    Sample Input

    9 6
    4 2 2 1 9 4 0 1 1
    2 1 4 3
    3 4 10
    2 1 4 3
    1 2 5 9
    4 3 9 5
    5 2 8 5

    Sample Output

    2
    4
    3
    4
    9

    HINT

    1.n和m的数据范围:n,m<=50000

    2.序列中每个数的数据范围:[0,1e8]

    3.虽然原题没有,但事实上5操作的k可能为负数
    所以说我可能真的不适合数据结构,泪流满面"^"
    我没有吃饭加浪费了一个晚自习的结果居然是一处maxv写成了maxn,终于没有写错splay居然又开错了数组有木有有木有。。。
    我这时的心情是悲愤的,然而并没有什么卵用,再立flag,明天数据结构绝对1A
    线段树套Splay,对于二号询问直接二分答案,Splay还是记得开哨兵
    有时候函数开多一点代码反而更好写
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long LL;
      4 template <class _T> inline void read(_T &_x) {
      5     int _t; bool flag = false;
      6     while ((_t = getchar()) != '-' && (_t < '0' || _t > '9')) ;
      7     if (_t == '-') _t = getchar(), flag = true; _x = _t - '0';
      8     while ((_t = getchar()) >= '0' && _t <= '9') _x = _x * 10 + _t - '0';
      9     if (flag) _x = -_x;
     10 }
     11 const int maxn = 50010;
     12 const int inf = 2147483647;
     13 namespace S {
     14     const int maxv = 4e6 + 5;
     15     int *root;
     16     int v[maxv], f[maxv], ch[maxv][2], sz[maxv], cnt[maxv];
     17     int st[maxv], top, tot;
     18     inline int newnode(int val) {
     19         if (!top) st[top++] = ++tot;
     20         int cur = st[--top];
     21         v[cur] = val;
     22         f[cur] = ch[cur][0] = ch[cur][1] = 0;
     23         sz[cur] = cnt[cur] = 1;
     24         return cur;
     25     }
     26     inline void update(int rt) {
     27         sz[rt] = sz[ch[rt][0]] + sz[ch[rt][1]] + cnt[rt];
     28     }
     29     inline void init(int &rt) {
     30         rt = newnode(-inf);
     31         ch[rt][1] = newnode(inf);
     32         f[ch[rt][1]] = rt;
     33         update(rt);
     34     }
     35     inline void rotate(int c) {
     36         int b = f[c], a = f[b], x = ch[b][1]==c;
     37         ch[b][x] = ch[c][x ^ 1], f[ch[b][x]] = b;
     38         ch[c][x ^ 1] = b, f[b] = c;
     39         if (a) ch[a][ch[a][1]==b] = c; else *root = c;
     40         f[c] = a; update(b);
     41     }
     42     inline int splay(int c, int a = 0) {
     43         for (int b; (b = f[c]) != a; rotate(c)) if (f[b] != a)
     44             rotate((ch[f[b]][1]==b)==(ch[b][1]==c)?b:c);
     45         update(c); return c;
     46     }
     47     inline int query_pre(int rt, int val) {
     48         int ret = 0, ori = f[rt];
     49         do {
     50             if (v[rt] < val) ret = rt;
     51             rt = ch[rt][v[rt] < val];
     52         } while (rt);
     53         return splay(ret, ori);
     54     }
     55     inline int query_suc(int rt, int val) {
     56         int ret = 0, ori = f[rt];
     57         do {
     58             if (v[rt] > val) ret = rt;
     59             rt = ch[rt][v[rt] <= val];
     60         } while (rt);
     61         return splay(ret, ori);
     62     }
     63     inline int pre(int rt, int a = 0) {
     64         rt = ch[rt][0];
     65         while (ch[rt][1]) rt = ch[rt][1];
     66         return splay(rt, a);
     67     }
     68     inline int suc(int rt, int a = 0) {
     69         rt = ch[rt][1];
     70         while (ch[rt][0]) rt = ch[rt][0];
     71         return splay(rt, a);
     72     }
     73     inline void remove(int rt, int val) {
     74         int x = query_pre(rt, val);
     75         int y = suc(x, x);
     76         if (cnt[y] > 1) --cnt[y];
     77         else {
     78             int z = suc(y, x);
     79             st[top++] = y, ch[z][0] = 0, y = z;
     80         }
     81         update(y), update(x);
     82     }
     83     inline void insert(int &rt, int val) {
     84         root = &rt;
     85         int x = query_pre(rt, val);
     86         int y = suc(x, x);
     87         if (v[y] == val) ++cnt[y];
     88         else {
     89             int z = ch[y][0] = newnode(val);
     90             f[z] = y;
     91         }
     92         update(y), update(x);
     93     }
     94     inline void change(int &rt, int ori, int to) {
     95         root = &rt;
     96         remove(rt, ori);
     97         insert(rt, to);
     98     }
     99     inline int Query_cnt(int &rt, int val) {
    100         root = &rt;
    101         query_suc(rt, val);
    102         return sz[ch[rt][0]] - 1;
    103     }
    104     inline int Query_suc(int &rt, int val) {
    105         root = &rt;
    106         return v[query_suc(rt, val)];
    107     }
    108     inline int Query_pre(int &rt, int val) {
    109         root = &rt;
    110         return v[query_pre(rt, val)];
    111     }
    112     inline int Query_rk(int &rt, int val) {
    113         root = &rt;
    114         int x = query_pre(rt, val);
    115         return sz[ch[x][0]] + cnt[x] - 1;
    116     }
    117 }
    118 int n, m, a[maxn], root[maxn * 20];
    119 #define lson rt << 1, l, mid
    120 #define rson rt << 1 | 1, mid + 1, r
    121 void build(int rt, int l, int r) {
    122     S::init(root[rt]);
    123     for (int i = l; i <= r; ++i)
    124         S::insert(root[rt], a[i]);
    125     if (l == r) return ;
    126     int mid = (l + r) >> 1;
    127     build(lson), build(rson);
    128 }
    129 int query_cnt(int rt, int l, int r, int L, int R, int val) { //cnt of less or equal
    130     if (L <= l && r <= R) return S::Query_cnt(root[rt], val);
    131     int mid = (l + r) >> 1, ret = 0;
    132     if (L <= mid) ret += query_cnt(lson, L, R, val);
    133     if (mid < R) ret += query_cnt(rson, L, R, val);
    134     return ret;
    135 }
    136 int query_pre(int rt, int l, int r, int L, int R, int val) { //less than val
    137     if (L <= l && r <= R) return S::Query_pre(root[rt], val);
    138     int mid = (l + r) >> 1, ret = -inf;
    139     if (L <= mid) ret = max(ret, query_pre(lson, L, R, val));
    140     if (mid < R) ret = max(ret, query_pre(rson, L, R, val));
    141     return ret;
    142 }
    143 int query_suc(int rt, int l, int r, int L, int R, int val) { //more than val
    144     if (L <= l && r <= R) return S::Query_suc(root[rt], val);
    145     int mid = (l + r) >> 1, ret = inf;
    146     if (L <= mid) ret = min(ret, query_suc(lson, L, R, val));
    147     if (mid < R) ret = min(ret, query_suc(rson, L, R, val));
    148     return ret;
    149 }
    150 int query_precnt(int rt, int l, int r, int L, int R, int val) {
    151     if (L <= l && r <= R) return S::Query_rk(root[rt], val);
    152     int mid = (l + r) >> 1, ret = 0;
    153     if (L <= mid) ret += query_precnt(lson, L, R, val);
    154     if (mid < R) ret += query_precnt(rson, L, R, val);
    155     return ret;
    156 }
    157 void update(int rt, int l, int r, int pos, int val) { // update pos to val
    158     S::change(root[rt], a[pos], val);
    159     if (l == r) return ;
    160     int mid = (l + r) >> 1;
    161     if (pos <= mid) update(lson, pos, val);
    162     else update(rson, pos, val);
    163 }
    164 inline int Query_kth(int L, int R, int k) {
    165     int l = 0, r = 1e8, mid;
    166     while (l < r) {
    167         mid = (l + r) >> 1;
    168         if (query_cnt(1, 1, n, L, R, mid) >= k) r = mid;
    169         else l = mid + 1;
    170     }
    171     return l;
    172 }
    173 inline int Query_pre(int L, int R, int val) {
    174     return query_pre(1, 1, n, L, R, val);
    175 }
    176 inline int Query_suc(int L, int R, int val) {
    177     return query_suc(1, 1, n, L, R, val);
    178 }
    179 inline int Query_rk(int L, int R, int val) {
    180     return query_precnt(1, 1, n, L, R, val) + 1;
    181 }
    182 inline void Update(int pos, int val) {
    183     update(1, 1, n, pos, val);
    184     a[pos] = val;
    185 }
    186 int main() {
    187     //freopen("3196.in", "r", stdin);
    188     //freopen("3196.out", "w", stdout);
    189     read(n), read(m);
    190     for (int i = 1; i <= n; ++i) read(a[i]);
    191     build(1, 1, n);
    192     for (int i = 1, op, x, y, z; i <= m; ++i) {
    193         read(op);
    194         switch (op) {
    195             case 1:
    196                 read(x), read(y), read(z);
    197                 printf("%d
    ", Query_rk(x, y, z));
    198                 break;
    199             case 2:
    200                 read(x), read(y), read(z);
    201                 printf("%d
    ", Query_kth(x, y, z));
    202                 break;
    203             case 3:
    204                 read(x), read(y);
    205                 Update(x, y);
    206                 break;
    207             case 4:
    208                 read(x), read(y), read(z);
    209                 printf("%d
    ", Query_pre(x, y, z));
    210                 break;
    211             case 5:
    212                 read(x), read(y), read(z);
    213                 printf("%d
    ", Query_suc(x, y, z));
    214                 break;
    215         }
    216     }
    217     return 0;
    218 }
    View Code
  • 相关阅读:
    BGP综合部署
    网络综合部署
    部署LNMP架构
    编译安装Nginx网站服务及优化
    Apache网页优化
    在windows上安装jupyter,配置单机版pyspark
    剑指offer54-字符流中第一个不重复的字符
    在centos001上安装jupyter,配置单机版pyspark
    剑指offer53-表示数值的字符串
    剑指offer50-数组中重复的数字
  • 原文地址:https://www.cnblogs.com/akhpl/p/6764895.html
Copyright © 2020-2023  润新知