洛谷P3332 [ZJOI2013]K大数查询(整体二分板题)

https://www.luogu.com.cn/problem/P3332

Code:

#include<bits/stdc++.h>

#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)

#define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)

#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)

#define ll long long

#define pp printf

#define hh pp("
")

using namespace std;



const int N = 50005;



int n, m;



struct nod {

	int op, i;

	ll x, y, z;

} a[N];


int ans[N];

#define V vector<int>
#define pb push_back
#define si size()

#define i0 i + i
#define i1 i + i + 1
ll t[N * 4], lz[N * 4];
int pl, pr;
ll px;

void jia(int i, int x, int y, ll v) {
	t[i] += v * (y - x + 1);
	lz[i] += v;
}
void down(int i, int x, int y) {
	if(lz[i]) {
		int m = x + y >> 1;
		jia(i0, x, m, lz[i]);
		jia(i1, m + 1, y, lz[i]);
		lz[i] = 0;
	}
}

void add(int i, int x, int y) {
	if(y < pl || x > pr) return;
	if(x >= pl && y <= pr) {
		jia(i, x, y, px);
		return;
	}
	int m = x + y >> 1; down(i, x, y);
	add(i0, x, m); add(i1, m + 1, y);
	t[i] = t[i0] + t[i1];
}

void ft(int i, int x, int y) {
	if(y < pl || x > pr) return;
	if(x >= pl && y <= pr) {
		px += t[i];
		return;
	}
	int m = x + y >> 1; down(i, x, y);
	ft(i0, x, m); ft(i1, m + 1, y);
}

void dg(int x, int y, V b) {
	if(b.empty()) return;
	if(x == y) {
		ff(i, 0, b.si) {
			int x = b[i];
			if(a[x].op == 2) ans[a[x].i] = -y;
		}
		return;
	}
	V c, d;
	int m = x + y >> 1;
	ff(i, 0, b.si) {
		int x = b[i];
		if(a[x].op == 1) {
			if(a[x].z <= m) {
				pl = a[x].x, pr = a[x].y, px = 1;
				add(1, 1, n);
				c.pb(x);
			} else {
				d.pb(x);
			}
		} else {
			pl = a[x].x, pr = a[x].y; px = 0;
			ft(1, 1, n);
			if(px < a[x].z) {
				a[x].z -= px;
				d.pb(x);
			} else {
				c.pb(x);
			}
		}
	}
	ff(i, 0, c.si) {
		int x = c[i];
		if(a[x].op == 1) {
			pl = a[x].x, pr = a[x].y, px = -1;
			add(1, 1, n);
		}
	}
	dg(x, m, c);
	dg(m + 1, y, d);
}

int main() {


	scanf("%d %d", &n, &m);

	fo(i, 1, m) {

		scanf("%d %lld %lld %lld", &a[i].op, &a[i].x, &a[i].y, &a[i].z);
		if(a[i].op == 1) a[i].z = -a[i].z;

		a[i].i = i;

	}
	V b; fo(i, 1, m) b.pb(i);
	dg(-1e9 - 1, 1e9, b);
	fo(i, 1, m) if(a[i].op == 2)
		pp("%d
", ans[i]);

}
原文地址:https://www.cnblogs.com/coldchair/p/13463311.html