【模板】权值线段树

#include "bits/stdc++.h"
using namespace std;
const int z = 131072;
const int INF = 0x7f7f7f7f;
int ROOT, LEFT, RIGHT;
struct NODE {
	int lt, rt;
	long long tot;
	int num;
} tree[z];
int cnt;
#define lt tree[id].lt
#define rt tree[id].rt
void pushup(int id) {
	tree[id].tot = tree[lt].tot+tree[rt].tot;
}//上传;
void update(int &id,int tl,int tr,int pos,int val) {
	if(!id) id = ++cnt;
	if(tl == tr) {
		++tree[id].tot;
		tree[id].num = val;
		return;
	}
	int mid = (tl+tr)>>1;
	if(pos <= mid) update(lt,tl,mid,pos,val);
	else update(rt,mid+1,tr,pos,val);
	pushup(id);
}//单点更新;
int query_tot(int id,int tl,int tr,int l,int r) {
	if(!id) return 0;
	if(l <= tr&&tr <= r) 
		return tree[id].tot;
	long long ans = 0;
	int mid = (l+r)>>1;
	if(l <= mid) ans += query_tot(lt,tl,mid,l,r);
	if(mid < r) ans += query_tot(rt,mid+1,tr,l,r);
	return ans;
}//查询区间数字个数;
int ranked_number(int id,int tl,int tr,int rk) {
	if(!id) return -INF;
	if(tl == tr) 
		return tree[id].num;
	int mid = (tr+tl)>>1;
	if(rk > tree[rt].tot) 
		return ranked_number(lt,tl,mid,rk-tree[rt].tot);
	else 
		return ranked_number(rt,mid+1,tr,rk);
}//查询某排名对应的数字;
int lower_count(int val) {
	return query_tot(ROOT,LEFT,RIGHT,LEFT,val-1);
}//查询小于某数字的数字的个数;
int upper_count(int val) {
	return query_tot(ROOT,LEFT,RIGHT,val+1,RIGHT);
}//查询大于某数字的数字的个数;
int get_rank(int val) {
	return lower_count(val)+1;
}//查询某数字对应的排名;
int pre(int val) {
	int help = lower_count(val);
	return ranked_number(ROOT,LEFT,RIGHT,help);
}//查询某数字的前驱;
int suc(int val) {
	int help = get_rank(val);
	return ranked_number(ROOT,LEFT,RIGHT,help+1);
}//查询某数字的后驱;
int main() {
	//to do;
}

@bikuhiku

posted @ 2022-07-20 14:07  bikuhiku  阅读(21)  评论(0编辑  收藏  举报