zoukankan      html  css  js  c++  java
  • 「LuoguP3369」 【模板】普通平衡树 (用vector乱搞平衡树

    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

    时空限制:1000ms,128M

    1.n的数据范围: n≤100000

    2.每个数的数据范围: [−107,107][-{10}^7, {10}^7]

    来源:Tyvj1728 原名:普通平衡树

    在此鸣谢

    题解

    这里用的是vector

    参(xue)考(xi)资料:Rye_Catcher的题解C++ vector用法_金河

    因为实在搞不清楚treap的旋转(令人头大  所以选择了万能的STL

    其实vector并不是有序的,但是我们可以自行维护vector的有序性。

    前置知识:(时间复杂度也不太确定 有问题希望大佬纠正

    • 定义:vector<int>a; 需<vector>头文件
    • 访问元素:a[x]  取出a中的第(x+1)个数(下标从0开始 O(1)
    • a.begin():返回起始元素的迭代器 O(1)
    • a.end():返回终止元素的迭代器 O(1)
    • a.insert(a.begin()+pos,x):在第pos个数后面插入x O(n)
    • a.erase(a.begin()+pos):删除pos位置的数 pos之后的数自动补齐 O(n)
    • lower_bound(a.begin(),a.end(),x)返回第一个==x的位置的迭代器 O(logn)
    • upper_bound(a.begin(),a.end(),x)返回最后一个==x的位置的后面一个的迭代器(x的后继 O(logn)
    • *it:取出迭代器it中的值(大概只有我不知道

    然后 你应该自己就懂了(嘿嘿嘿

    对着代码理解吧

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<vector>
     4 using namespace std;
     5 vector<int>a;
     6 int main()
     7 {
     8     int n;
     9     cin>>n;
    10     for(int i=1;i<=n;++i)
    11     {
    12         int opt,x;
    13         scanf("%d%d",&opt,&x);
    14         switch(opt)
    15         {
    16             case(1):a.insert(upper_bound(a.begin(),a.end(),x),x);break;//插入
    17             case(2):a.erase(lower_bound(a.begin(),a.end(),x));break;//删除
    18             case(3):cout<<lower_bound(a.begin(),a.end(),x)-a.begin()+1<<endl;break;//输出x的排名
    19             case(4):cout<<a[x-1]<<endl;break;//输出第x的数
    20             case(5):cout<<*--lower_bound(a.begin(),a.end(),x)<<endl;break;//x的前趋
    21             case(6):cout<<*upper_bound(a.begin(),a.end(),x)<<endl;break;//x的后继
    22         }
    23     }
    24     return 0;
    25 }

     UPD

    新学的set,但是支持的操作肽少了qwq

    关于排名的只能用很慢的distance($O(n)$)和advance($O(n)$)qwq

    然后还是照着之前那篇题解学的。

    嗯。

     1 /*
     2  qwerta 
     3 P3369 【模板】普通平衡树 Unaccepted 
     4 64
     5 代码 C++,0.57KB
     6 提交时间 2018-10-31 21:39:58
     7 耗时/内存 5756ms, 2820KB
     8 */
     9 #include<iostream>
    10 #include<cstdio>
    11 #include<set>
    12 using namespace std;
    13 multiset<int>s;
    14 int main()
    15 {
    16     //freopen("a.in","r",stdin);
    17     int n;
    18     scanf("%d",&n);
    19     while(n--)
    20     {
    21         int opt,x;
    22         scanf("%d%d",&opt,&x);
    23         switch(opt)
    24         {
    25             case(1):s.insert(x);break;
    26             case(2):s.erase(s.lower_bound(x));break;
    27             case(3):cout<<distance(s.begin(),s.lower_bound(x))+1<<endl;break;
    28             case(4):{multiset<int>::iterator it=s.begin();
    29             advance(it,x-1);cout<<(*it)<<endl;break;}
    30             case(5):cout<<(*--s.lower_bound(x))<<endl;break;
    31             case(6):cout<<(*s.upper_bound(x))<<endl;break;
    32         }
    33     }
    34     return 0;
    35 }
  • 相关阅读:
    Linux 中 eclipse 的tomcat端口号被占用
    JDBC的常用API
    eclipse Alt+/ 无法提示代码
    javaweb项目开发错误代码
    PSP总结报告
    20181204-1 每周例行报告
    对团队成员公开感谢博客
    20181127-2 每周例行报告
    20181120-1 每周例行报告
    20181113-2 每周例行报告
  • 原文地址:https://www.cnblogs.com/qwerta/p/9384774.html
Copyright © 2011-2022 走看看