[ZJOI2013]K大数查询

权值线段树套线段树模板
区间每个可重集插入一个数
把权值放外边,内部维护区间
在权值线段树上二分,内部查询数量

\(\text{Code}\)

#include <cstdio>
#include <iostream>
#define LL long long
using namespace std;

const int N = 5e4;
int n, m, rt, seg_size, tr_size;
struct segment{int ls, rs, tg; LL s;}seg[N * 270 + 5];
struct tree{int ls, rs, rt;}T[N * 8 + 5];

inline void pushdown(int p, int tl, int tr)
{
	if (!seg[p].tg)	return;
	LL v = seg[p].tg;
	if (!seg[p].ls) seg[p].ls = ++seg_size; 
	if (!seg[p].rs) seg[p].rs = ++seg_size;
	int mid = (tl + tr) >> 1;
	seg[seg[p].ls].s += v * (mid - tl + 1), seg[seg[p].ls].tg += v;
	seg[seg[p].rs].s += v * (tr - mid), seg[seg[p].rs].tg += v;
	seg[p].tg = 0;
}
void update(int &p, int tl, int tr, int l, int r)
{
	if (!p) p = ++seg_size;
	seg[p].s += min(tr, r) - max(tl, l) + 1;
	if (l <= tl && tr <= r) return void(++seg[p].tg);
	pushdown(p, tl, tr);
	int mid = (tl + tr) >> 1;
	if (l <= mid) update(seg[p].ls, tl, mid, l, r);
	if (r > mid) update(seg[p].rs, mid + 1, tr, l, r);
}
LL query(int p, int tl, int tr, int l, int r)
{
	if (!p || (l <= tl && tr <= r)) return seg[p].s;
	pushdown(p, tl, tr);
	int mid = (tl + tr) >> 1; LL res = 0;
	if (l <= mid) res = query(seg[p].ls, tl, mid, l, r);
	if (r > mid) res += query(seg[p].rs, mid + 1, tr, l, r);
	return res;
}

void Update(int &p, int tl, int tr, int l, int r, LL k)
{
	if (!p) p = ++tr_size;
	update(T[p].rt, 1, n, l, r);
	if (tl == tr) return;
	int mid = (tl + tr) >> 1;
	if (k <= mid) Update(T[p].ls, tl, mid, l, r, k);
	else Update(T[p].rs, mid + 1, tr, l, r, k);
}
int Query(int p, int tl, int tr, int l, int r, LL k)
{
	if (tl == tr) return tl;
	int mid = (tl + tr) >> 1;
	LL sum = query(T[T[p].rs].rt, 1, n, l, r);
	if (k <= sum) return Query(T[p].rs, mid + 1, tr, l, r, k);
	return Query(T[p].ls, tl, mid, l, r, k - sum);
}

int main()
{
	scanf("%d%d", &n, &m);
	int l, r, op; LL k;
	for(; m; --m)
	{
		scanf("%d%d%d%lld", &op, &l, &r, &k);
		if (op == 1) Update(rt, -n, n, l, r, k);
		else printf("%d\n", Query(rt, -n, n, l, r, k));
	}
}
上一篇:AtCoder Beginner Contest 221 E - LEQ (计数,线段树)


下一篇:ORACLE UPDATE 多表关联的update语句