问题是我们要在$[L,R]$的区间内找第一个在$pos$前面/后面出现的值。

这个可以转化为在权值线段树上找前驱后继。

前驱问题的具体解决方法是。

如果$pos$在当前区间的左半边那么答案一定在左区间,于是递归到左区间寻找。

否则优先在右区间进行寻找,如果找到答案的话就返回,否则再在左区间寻找。

    int getpre(int l, int r, int o1, int o2, int pos)
    {
        if (!(tr[o2] - tr[o1])) return 0;
        if (l == r) return l;
        int mid = (l + r) >> 1;
        if (pos <= mid) return getpre(l, mid, ls[o1], ls[o2], pos);
        int t = getpre(mid + 1, r, rs[o1], rs[o2], pos);
        if (t) return t; 
        return getpre(l, mid, ls[o1], ls[o2], pos);
    }

 

查询后继类似。

    int getnxt(int l, int r, int o1, int o2, int pos)
    {
        if (!(tr[o2] - tr[o1])) return 0;
        if (l == r) return l;
        int mid = (l + r) >> 1;
        if (pos > mid) return getnxt(mid + 1, r, rs[o1], rs[o2], pos);
        int t = getnxt(l, mid, ls[o1], ls[o2], pos);
        if (t) return t;
        return getnxt(mid + 1, r, rs[o1], rs[o2], pos);
    }

 

相关文章:

  • 2022-12-23
  • 2021-07-27
  • 2021-07-10
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-08-18
  • 2022-12-23
  • 2021-07-29
  • 2022-12-23
相关资源
相似解决方案