%\%

#include <bits/stdc++.h>
using namespace std;
const int N = 1e7;
int n, m, q, l, r, x;
int a[N], sum[4 * N];
void pushup(int rt)
{
	sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void build(int l, int r, int rt)//建树 
{
	if(l == r){ sum[rt] = 0; return;}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	pushup(rt);
}
void update(int l, int r, int rt, int x, int d)//单点修改 
{
	if(l == r){ sum[rt] = d; return;}
	int mid = (l + r) >> 1;
	if(x <= mid) update(l, mid, rt << 1, x, d);
	else update(mid + 1, r, rt << 1 | 1, x, d);
	pushup(rt);
}
int query(int l, int r, int rt, int x, int y)//区间查询 
{
	if(x > r || y < l) return 0;
	if(x <= l && r <= y) return sum[rt];//区间[x,y]包含[l,r]
	int mid = (l + r) >> 1;
	int ans = 0;
	if(x <= mid) ans += query(l, mid, rt << 1, x, y);
	if(y > mid) ans += query(mid + 1, r, rt << 1 | 1, x, y);
	return ans;
}
int kth(int l, int r, int rt, int k)//求第k小的数 
{
	if(l == r) return r;//到达叶子结点
	int mid = (l + r) >> 1;
	int lsum = sum[rt << 1];
	if(k <= lsum) return kth(l, mid, rt << 1, k);
	return kth(mid + 1, r, rt << 1 | 1, k - lsum);
}
int pre(int x)//查找前驱 
{
	int k = query(1, N, 1, 1, x - 1);
	if(!k) return -1;//它是最小值,无前驱
	return kth(1, N, 1, k); 
} 
int next(int x, int mx)
{
	int k = query(1, N, 1, 1, x - 1) + 1;
	if(!(k ^ mx)) return -1;//它是最大值,无前驱
	return kth(1, N, 1, k); 
}
int main()
{

    return 0;
}

动态开点

#include <bits/stdc++.h>
using namespace std;
const int N = 1e7;
struct node{
    int lson, rson, sum;
}T[N * 3];
int n, opt, x, cnt = 1, root = 1;
void update(int rt, int l, int r, int k, int v)//更新数值 
{
    if(l == r){
        T[rt].sum += v;
        return;
    }
    int mid = (l + r) >> 1;
    if(k <= mid){
    	if(!T[rt].lson) T[rt].lson = ++cnt;
    	update(T[rt].lson, l, mid, k, v);
	}
    else{
    	if(!T[rt].rson) T[rt].rson = ++cnt; 
    	update(T[rt].rson, mid + 1, r, k, v);
	}
    T[rt].sum = T[T[rt].lson].sum + T[T[rt].rson].sum;//类似pushup 
}
int query(int l, int r, int rt, int x, int y)//区间求和
{ 
    if(rt == 0)return 0;
    if(x <= l && r <= y) return T[rt].sum; 
    int s = 0;
    int mid = (l + r) >> 1;
    if(x <= mid) s += query(T[rt].lson, l, mid, x, y);
    if(y > mid) s += query(T[rt].rson, mid + 1, r, x, y);
    return s;
}
int kth(int rt, int l, int r, int k)//找第K个数 
{
    if(l == r) return r;
    int mid = (l + r) >> 1;
    int lson = T[rt].lson;
    int rson = T[rt].rson;
    if(T[lson].sum >= k)return kth(lson, l, mid, k);//左子树总数量>=k,那么第k个肯定在左子树 
    return kth(rson, mid + 1, r, k - T[lson].sum);//第k个在右子树,递归右子树,注意k值的变化
}
int main()
{
	
	return 0;
}