zoukankan      html  css  js  c++  java
  • Bsoj 1322 第K小数

    第K小数
    Description
      现在已有N个整数,你有以下三种操作:
    1 A:表示加入一个值为A的整数;
    2 B:表示删除其中值为B的整数;
    3 K:表示输出这些整数中第K小的数;
    Input
    第一行,两个整数N,M,表示最开始有N个整数,总共有M个操作
    第二行用空格隔开的N个整数
    接下来M行,每行表示一个操作
    Output
    若干行,一行一个整数,表示所求的第K小的数字
    Sample Input
    5 5
    6 2 7 4 9
    1 8
    1 6
    3 10
    2 4
    3 3
    Sample Output
    0
    7
    Hint
    【注意】:如果有多个大小相同的数字,只把他们看做一个数字,如样例。 若找不到第K小的数,输出0
    【数据范围】
    0<=N<=2,000,000
    M<=1,000,000
    -1,000,000,000<=每个整数<=1,000,000,000

    写个普通的treap就好

      1 /*by SilverN*/
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<cstring>
      6 #include<algorithm>
      7 using namespace std;
      8 int n,m;
      9 struct treap{
     10     int l,r;//左右子树 
     11     int val,ct;//值 重复次数 
     12     int size,rand;//管控数量,随机权值 
     13 }t[120000];
     14 int root=0,cnt=0;
     15 int ans;
     16 void update(int k){
     17     t[k].size=t[t[k].l].size+t[t[k].r].size+t[k].ct;
     18 }
     19 void lt(int &k){//左旋 
     20     int now=t[k].r;
     21     t[k].r=t[now].l;
     22     t[now].l=k;
     23     t[now].size=t[k].size;
     24     update(k);
     25     k=now;
     26     return;
     27 }
     28 void rt(int &k){
     29     int now=t[k].l;
     30     t[k].l=t[now].r;
     31     t[now].r=k;
     32     t[now].size=t[k].size;
     33     update(k);
     34     k=now;
     35     return;
     36 }
     37 void insert(int &k,int x){
     38     if(k==0){
     39         t[++cnt].val=x;
     40         t[cnt].size=1;
     41         t[cnt].ct=1;
     42         t[cnt].rand=rand();
     43         k=cnt;
     44         return;
     45     } 
     46     t[k].size++;
     47     if(t[k].val==x) return;//多个重复数字看做一个 
     48     else if(x>t[k].val){
     49         insert(t[k].r,x);
     50         if(t[t[k].r].rand<t[k].rand) lt(k);
     51     }else{//x<t[k].val
     52         insert(t[k].l,x);
     53         if(t[t[k].l].rand<t[k].rand) rt(k);
     54     }
     55     return;
     56 }
     57 void del(int &k,int x){
     58     if(k==0)return;
     59     if(t[k].val==x){
     60         if(t[k].ct>1){t[k].ct--;t[k].size--;return;}
     61         if(t[k].l*t[k].r==0)k=t[k].l+t[k].r;//如果k是链结点(只有一个子节点),由其子节点补位 
     62         else{
     63             if(t[t[k].l].rand<t[t[k].r].rand){
     64                 rt(k);
     65                 del(k,x);
     66             }
     67             else{
     68                 lt(k);
     69                 del(k,x);
     70             }
     71         }
     72         return;
     73     }
     74     t[k].size--;
     75     if(x>t[k].val)del(t[k].r,x);
     76     if(x<t[k].val)del(t[k].l,x);
     77     return;
     78 }
     79 int ask_num(int k,int x){// 已知排名问数字 
     80     if(!k)return 0;
     81     if(x<=t[t[k].l].size)return ask_num(t[k].l,x);//排名小于左子树包含结点数量,则往左查 
     82     if(x>t[t[k].l].size+t[k].ct)return ask_num(t[k].r,x-t[t[k].l].size-t[k].ct);
     83     //排名大于“左子树结点数加父结点重复数”,则往右查 
     84     else return t[k].val;//否则返回父结点值 
     85 }
     86 int main(){
     87     int opt,x;
     88     scanf("%d%d",&n,&m);
     89     for(int i=1;i<=n;i++){
     90         scanf("%d",&x);
     91         insert(root,x);
     92     }
     93     while(m--){
     94         scanf("%d%d",&opt,&x);
     95         switch(opt){
     96             case 1:    insert(root,x);    break;
     97             case 2: del(root,x); break;                
     98             case 3: printf("%d
    ",ask_num(root,x));break;
     99         }
    100 //        for(int i=1;i<=cnt;i++)printf("%d ",t[i].val);
    101 //        cout<<endl;
    102     }
    103     return 0;
    104 }
  • 相关阅读:
    Xcode升级7.3 自动补全不提示导入的自定义类解决方案
    workspace & subProject & target
    iOS开发笔记:编译时出现的错误和解决办法
    Apple iOS推送证书配置和生成教程
    UITextField总结--博主总结的真好
    maven库
    数据库事务四种属性
    redis 相关知识
    MySQL索引
    Mybatis 常用标签
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5568704.html
Copyright © 2011-2022 走看看