zoukankan      html  css  js  c++  java
  • soj102 普通平衡树

    题意:

    标程:

     1 #include<cstdio>
     2 using namespace std;
     3 int read()
     4 {
     5     int x=0,f=1;char ch=getchar();
     6     while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
     7     while ('0'<=ch&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
     8     return x*f; 
     9 }
    10 const int N=5000000;
    11 int bit[N+2],op,x,n;
    12 int lowbit(int x){return x&(-x);}
    13 void add(int x,int y) {while (x<=N) bit[x]+=y,x+=lowbit(x);}
    14 int sum(int x){int res=0;while (x) res+=bit[x],x-=lowbit(x);return res;}
    15 int kth(int k)
    16 {
    17     if (!k||sum(N)<k) return -1;
    18     int l=0,r;
    19     for (int i=22;i>=0&&k;i--)
    20       if ((r=l+(1<<i))<=N&&bit[r]<k) k-=bit[l=r]; 
    21     return l+1;
    22 }
    23 int main()
    24 {
    25     n=read();
    26     while (n--)
    27     {
    28         op=read(),x=read();
    29         if (op==1) {if (!(sum(x)-sum(x-1))) add(x,1);}else
    30         if (op==2) {if (sum(x)-sum(x-1)) add(x,-1);}else
    31         if (op==3) printf("%d
    ",sum(x-1)+1);else
    32         if (op==4) printf("%d
    ",kth(x));else
    33         if (op==5) printf("%d
    ",kth(sum(x-1)));else
    34         printf("%d
    ",kth(sum(x)+1));
    35     }
    36     return 0;
    37 } 

    易错点:1.注意5e6有2^22。

    2.二分时先找到sum=k-1的最远处,然后+1,即是sum=k的第一点。

    题解:树状数组+二分

    由于这道题xi比较小,我们不用splay,直接用树状数组即可。

    树状数组维护一个数值是否出现。

    查询第k个直接在bit上二分即可,类似于倍增,因为树状数组上的每一段都是2的幂次,每一个数都是若干2的幂次的和。树状数组单点的话:除sum(x)-sum(x-1)外也可以用下面的方法:

    int ans=bit[x];for (int i=x-1;i!=x-lowbit(x);i-=lowbit(i)) ans-=bit[i];因为在x-lowbit(x)的前面一段是互相抵消的,只需要计算最后一段lowbit的差即可。

  • 相关阅读:
    2018年全国多校算法寒假训练营练习比赛(第二场)F
    牛客练习赛2 A
    牛客练习赛1 C
    牛客练习赛1 B
    vb编程代码大全
    javascript编程代码笔记
    391.FANUC宏程序编程
    宏程序编程实例,简单易懂
    Java类与类之间的关系详细介绍
    C++虚继承时的构造函数的讲解
  • 原文地址:https://www.cnblogs.com/Scx117/p/8807335.html
Copyright © 2011-2022 走看看