zoukankan      html  css  js  c++  java
  • 3224: Tyvj 1728 普通平衡树(finger tree)

    3224: Tyvj 1728 普通平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 19122  Solved: 8359
    [Submit][Status][Discuss]

    Description

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
    1. 插入x数
    2. 删除x数(若有多个相同的数,因只删除一个)
    3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
    4. 查询排名为x的数
    5. 求x的前驱(前驱定义为小于x,且最大的数)
    6. 求x的后继(后继定义为大于x,且最小的数)

    Input

    第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

    Output

    对于操作3,4,5,6每行输出一个数,表示对应答案

    Sample Input

    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598

    Sample Output

    106465
    84185
    492737

    HINT

    1.n的数据范围:n<=100000

    2.每个数的数据范围:[-2e9,2e9]
     
     
     

    分析

    学了一个神奇的平衡树,叫:finger tree

    贴一下模板。。

    code

      1 #include<cstdio>
      2 #include<algorithm>
      3 #define ls ch[cur][0]
      4 #define rs ch[cur][1]
      5 
      6 using namespace std;
      7 
      8 const int N = 200100;
      9 
     10 int siz[N],val[N],ch[N][2],q[N];
     11 int tot,cnt,Root;
     12 
     13 int getid() {
     14     return tot?q[tot--]:++cnt;
     15 }
     16 void pushup(int cur) {
     17     if (!siz[ls]) return; // -
     18     siz[cur] = siz[ls] + siz[rs];
     19     val[cur] = val[rs];
     20 }
     21 int newNode(int v) {
     22     int cur = getid();
     23     siz[cur] = 1;val[cur] = v;
     24     ls = rs = 0;
     25     return cur;
     26 }
     27 void copyNode(int x,int y) {
     28     ch[x][0] = ch[y][0];ch[x][1] = ch[y][1];
     29     siz[x] = siz[y];val[x] = val[y];
     30 }
     31 int Merge(int x,int y) {
     32     int cur = getid();
     33     val[cur] = val[y];siz[cur] = siz[x]+siz[y]; //---
     34     ls = x;rs = y;
     35     return cur;
     36 }
     37 void lturn(int cur) {
     38     ls = Merge(ls,ch[rs][0]);
     39     q[++tot] = rs;
     40     rs = ch[rs][1];
     41 }
     42 void rturn(int cur) {
     43     rs = Merge(ch[ls][1],rs);
     44     q[++tot] = ls;
     45     ls = ch[ls][0];
     46 }
     47 void Maintain(int cur) {
     48     if (rs && siz[ls] > siz[rs] * 4) rturn(cur);
     49     if (ls && siz[rs] > siz[ls] * 4) lturn(cur);
     50 }
     51 void Insert(int cur,int x) {
     52     if (siz[cur]==1) {
     53         ls = newNode(min(val[cur],x));
     54         rs = newNode(max(val[cur],x));
     55         pushup(cur);
     56         return ;
     57     }
     58     if (x > val[ls]) Insert(rs,x);
     59     else Insert(ls,x);
     60     pushup(cur);
     61     Maintain(cur);
     62 }
     63 void Delete(int cur,int fa,int x) {
     64     if (siz[cur]==1) {
     65         if (ch[fa][0] == cur) copyNode(fa,ch[fa][1]); //-----
     66         else copyNode(fa,ch[fa][0]);
     67         return;
     68     }
     69     fa = cur;
     70     if (x > val[ls]) Delete(rs,cur,x);
     71     else Delete(ls,cur,x);
     72     pushup(cur);
     73     Maintain(cur);
     74 }
     75 int getrnk(int cur,int x) {
     76     if (siz[cur]==1) return 1;
     77     //{
     78     //    if (x > val[cur]) return 2;
     79     //    return 1;
     80     //}
     81     if (x > val[ls]) 
     82         return getrnk(rs,x) + siz[ls];
     83     else return getrnk(ls,x);
     84 }
     85 int getkth(int cur,int k) {
     86     if (siz[cur]==k) return val[cur];
     87     if (k > siz[ls]) 
     88         return getkth(rs,k-siz[ls]);
     89     else return getkth(ls,k);
     90 }
     91 int main () {
     92     int T;
     93     scanf("%d",&T);
     94     Root = newNode(1e9);
     95     while (T--) {
     96         int opt,x;
     97         scanf("%d%d",&opt,&x);
     98         if (opt==1) Insert(Root,x);
     99         else if (opt==2) Delete(Root,Root,x);
    100         else if (opt==3) printf("%d
    ",getrnk(Root,x));
    101         else if (opt==4) printf("%d
    ",getkth(Root,x));
    102         else if (opt==5) printf("%d
    ",getkth(Root,getrnk(Root,x)-1));
    103         else  printf("%d
    ",getkth(Root,getrnk(Root,x+1))); // ---
    104     }
    105     return 0;
    106 }
    View Code

    模板的变迁史:

      1 #include<cstdio>
      2 #include<algorithm>
      3 
      4 using namespace std;
      5 
      6 const int N = 200100;
      7 
      8 int siz[N],val[N],ch[N][2];
      9 int q[N],tot;
     10 int cnt;
     11 int Root;
     12 
     13 int getid() {
     14     return tot?q[tot--]:++cnt;
     15 }
     16 void pushup(int x) {
     17     if (!siz[ch[x][0]]) return; // -
     18     siz[x] = siz[ch[x][0]] + siz[ch[x][1]];
     19     val[x] = val[ch[x][1]];
     20 }
     21 int newNode(int v) {
     22     int cur = getid();
     23     siz[cur] = 1;val[cur] = v;
     24     ch[cur][0] = ch[cur][1] = 0;
     25     return cur;
     26 }
     27 void copyNode(int x,int y) {
     28     ch[x][0] = ch[y][0];ch[x][1] = ch[y][1];
     29     siz[x] = siz[y];val[x] = val[y];
     30 }
     31 int merge(int x,int y) {
     32     int cur = getid();
     33     val[cur] = val[y];siz[cur] = siz[x]+siz[y]; //---
     34     ch[cur][0] = x;ch[cur][1] = y;
     35     return cur;
     36 }
     37 void lturn(int cur) {
     38     ch[cur][0] = merge(ch[cur][0],ch[ch[cur][1]][0]);
     39     q[++tot] = ch[cur][1];
     40     ch[cur][1] = ch[ch[cur][1]][1];
     41 }
     42 void rturn(int cur) {
     43     ch[cur][1] = merge(ch[ch[cur][0]][1],ch[cur][1]);
     44     q[++tot] = ch[cur][0];
     45     ch[cur][0] = ch[ch[cur][0]][0];
     46 }
     47 void maintain(int cur) {
     48     if (ch[cur][1] && siz[ch[cur][0]] > siz[ch[cur][1]] * 4) rturn(cur);
     49     if (ch[cur][0] && siz[ch[cur][1]] > siz[ch[cur][0]] * 4) lturn(cur);
     50 }
     51 void Insert(int cur,int x) {
     52     if (siz[cur]==1) {
     53         ch[cur][0] = newNode(min(val[cur],x));
     54         ch[cur][1] = newNode(max(val[cur],x));
     55         pushup(cur);
     56         return ;
     57     }
     58     if (x > val[ch[cur][0]]) Insert(ch[cur][1],x);
     59     else Insert(ch[cur][0],x);
     60     pushup(cur);
     61     maintain(cur);
     62 }
     63 void Delete(int cur,int fa,int x) {
     64     if (siz[cur]==1) {
     65         if (ch[fa][0] == cur) copyNode(fa,ch[fa][1]); //-----
     66         else copyNode(fa,ch[fa][0]);
     67         return;
     68     }
     69     fa = cur;
     70     if (x > val[ch[cur][0]]) Delete(ch[cur][1],cur,x);
     71     else Delete(ch[cur][0],cur,x);
     72     pushup(cur);
     73     maintain(cur);
     74 }
     75 int rnk(int cur,int x) {
     76     if (siz[cur]==1) return 1;
     77     //{
     78     //    if (x > val[cur]) return 2;
     79     //    return 1;
     80     //}
     81     if (x > val[ch[cur][0]]) 
     82         return rnk(ch[cur][1],x) + siz[ch[cur][0]];
     83     else return rnk(ch[cur][0],x);
     84 }
     85 int kth(int cur,int k) {
     86     if (siz[cur]==k) return val[cur];
     87     if (k > siz[ch[cur][0]]) 
     88         return kth(ch[cur][1],k-siz[ch[cur][0]]);
     89     else return kth(ch[cur][0],k);
     90 }
     91 int main () {
     92     int T;
     93     scanf("%d",&T);
     94     Root = newNode(1e9);
     95     while (T--) {
     96         int opt,x;
     97         scanf("%d%d",&opt,&x);
     98         if (opt==1) Insert(Root,x);
     99         else if (opt==2) Delete(Root,Root,x);
    100         else if (opt==3) printf("%d
    ",rnk(Root,x));
    101         else if (opt==4) printf("%d
    ",kth(Root,x));
    102         else if (opt==5) printf("%d
    ",kth(Root,rnk(Root,x)-1));
    103         else  printf("%d
    ",kth(Root,rnk(Root,x+1))); // ---
    104     }
    105     return 0;
    106 }
    View Code

    指针

     1 // luogu-judger-enable-o2
     2 #include<cstdio>
     3 #include<iostream>
     4 
     5 using namespace std;
     6 
     7 const int MAXN = 400010;
     8 
     9 struct Node {
    10     int val,size;
    11     Node *ls,*rs;
    12     Node():val(0),size(0),ls(NULL),rs(NULL) { } 
    13     Node(int v,int s,Node *l,Node *r) {
    14         val = v,size = s,ls = l,rs = r;
    15     }
    16     bool isleaf() {
    17         return ls == NULL;
    18     }
    19     void pushup() {
    20         if (!isleaf()) {
    21             size = ls->size + rs->size;
    22             val = max(ls->val,rs->val);
    23         }
    24     }
    25 }pool[MAXN];
    26 
    27 Node *newNode(int val,int size,Node *ls,Node *rs) {
    28     static int cnt = 0;
    29     pool[cnt] = Node(val,size,ls,rs);
    30     return &pool[cnt++];
    31 }
    32 
    33 void insert(Node *&cur,int x) {
    34     if (cur==NULL) cur = newNode(x,1,NULL,NULL);
    35     else {
    36         if (cur->isleaf()) {
    37             cur->ls = newNode(min(x,cur->val),1,NULL,NULL);
    38             cur->rs = newNode(max(x,cur->val),1,NULL,NULL);
    39         }
    40         else {
    41             if (x > cur->ls->val) insert(cur->rs,x);
    42             else insert(cur->ls,x);
    43         }
    44         cur -> pushup();
    45     }
    46 }
    47 void erase(Node *cur,Node *fa,int x) {
    48     if (cur->isleaf()) {
    49         if (fa->ls == cur) *fa = *fa->rs;
    50         else *fa = *fa->ls;
    51     }
    52     else  {
    53         if (x > cur->ls->val) erase(cur->rs,cur,x);
    54         else erase(cur->ls,cur,x);
    55         cur -> pushup();
    56     }
    57 }
    58 int rnk(Node *cur,int x) {
    59     if (cur->isleaf()) {
    60         if (x > cur->val) return 2;
    61         return 1;
    62     }
    63     else {
    64         if (x > cur->ls->val) 
    65             return rnk(cur->rs,x)+cur->ls->size;
    66         else return rnk(cur->ls,x);
    67     }
    68 }
    69 int kth(Node *cur,int k) {
    70     if (cur->isleaf()) return cur->val;
    71     else {
    72         if (k > cur->ls->size) 
    73             return kth(cur->rs,k - cur->ls->size);
    74         else return kth(cur->ls,k);
    75     }
    76 }
    77 int main () {
    78     int T;
    79     scanf("%d",&T);
    80     Node *root = NULL;
    81     while (T--) {
    82         int opt,x;
    83         scanf("%d%d",&opt,&x);
    84         if (opt==1) insert(root,x);
    85         else if (opt==2) erase(root,root,x);
    86         else if (opt==3) printf("%d
    ",rnk(root,x));
    87         else if (opt==4) printf("%d
    ",kth(root,x));
    88         else if (opt==5) printf("%d
    ",kth(root,rnk(root,x)-1));
    89         else  printf("%d
    ",kth(root,rnk(root,x+1)));
    90     }
    91     return 0;
    92 }
    View Code
  • 相关阅读:
    magent + memcached 集群测试
    SQL Server 2000/2005检测存储过程名是否存在,存在删除
    ASP.NET在线用户列表精确版——解决用户意外退出在线列表无法及时更新问题
    使用asp.net/c# ajax 乱码的解决办法
    清空删除mssql数据库日志原文网址:http://admin.88443.net/article.
    net2.0下的简繁转换
    创建和注册自定义 httpModules 模块
    监控用户是否关闭浏览器
    Asp.net(Ajax)表单验证 函数包
    IE自带的网页过渡特效
  • 原文地址:https://www.cnblogs.com/mjtcn/p/8441222.html
Copyright © 2011-2022 走看看