【HDU 5283】Senior's Fish

http://acm.hdu.edu.cn/showproblem.php?pid=5283
今天的互测题,又爆零了qwq
考虑每个点对答案的贡献。
对每个点能产生贡献的时间线上的左右端点整体二分。
最后扫一遍即可,\(O(n\log^2n)\)
拍了好长时间,结果暴力标算都写错了,我不滚粗谁滚粗?

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 100003;

struct node {int op, l, r, d;} Q[N];
struct data {int x, y, lx, rx, ly, ry;} P[N];
int n, x1, y1, x2, y2, m, bits[N];

struct gagaga {int id, rest, ans;} B[N], A[N];

void add(int x, int num) {
	for (; x <= n; x += (x & (-x)))
		bits[x] += num;
}

int query(int x) {
	int ret = 0; if (x < 0) return 0;
	for (; x; x -= (x & (-x)))
		ret += bits[x];
	return ret;
}

void solve(int l, int r, int L, int R, int flag) {
	if (L > R) return;
	if (l == r) {
		for (int i = L; i <= R; ++i)
			B[i].ans = l;
		return;
	}
	int mid = (l + r) >> 1;
	for (int i = l; i <= mid; ++i)
		if (Q[i].op == flag) {
			add(Q[i].l, Q[i].d);
			add(Q[i].r + 1, -Q[i].d);
		}
	
	int tmp1 = L, tmp2 = R, t;
	for (int i = L; i <= R; ++i)
		if ((t = query(B[i].id)) >= B[i].rest)
			A[tmp1++] = B[i];
		else {
			B[i].rest -= t;
			A[tmp2--] = B[i];
		}
	for (int i = L; i <= R; ++i) B[i] = A[i];
	
	for (int i = l; i <= mid; ++i)
		if (Q[i].op == flag) {
			add(Q[i].l, -Q[i].d);
			add(Q[i].r + 1, Q[i].d);
		}
	
	solve(l, mid, L, tmp2, flag);
	solve(mid + 1, r, tmp1, R, flag);
}

void add_m(int x, int num) {
	for (; x <= m + 1; x += (x & (-x)))
		bits[x] += num;
}

struct hahaha {
	int type, l, r, pos, delta;
	bool operator < (const hahaha &A) const {
		return pos == A.pos ? type < A.type : pos < A.pos;
	}
} H[N << 2];

int main() {
	int T; scanf("%d", &T);
	while (T--) {
		scanf("%d%d%d%d%d", &n, &x1, &y1, &x2, &y2);
		for (int i = 1; i <= n; ++i) scanf("%d%d", &P[i].x, &P[i].y);
		scanf("%d", &m);
		for (int i = 1; i <= m; ++i) {
			scanf("%d%d%d", &Q[i].op, &Q[i].l, &Q[i].r);
			if (Q[i].op != 3) scanf("%d", &Q[i].d);
		}
		
		for (int i = 1; i <= n; ++i) B[i] = (gagaga) {i, x1 - P[i].x, 0};
		solve(1, m + 1, 1, n, 1);
		for (int i = 1; i <= n; ++i) P[B[i].id].lx = B[i].ans;
		
		for (int i = 1; i <= n; ++i) B[i] = (gagaga) {i, x2 + 1 - P[i].x, m + 1};
		solve(1, m + 1, 1, n, 1);
		for (int i = 1; i <= n; ++i) P[B[i].id].rx = B[i].ans;
		
		for (int i = 1; i <= n; ++i) B[i] = (gagaga) {i, y1 - P[i].y, 0};
		solve(1, m + 1, 1, n, 2);
		for (int i = 1; i <= n; ++i) P[B[i].id].ly = B[i].ans;
		
		for (int i = 1; i <= n; ++i) B[i] = (gagaga) {i, y2 + 1 - P[i].y, m + 1};
		solve(1, m + 1, 1, n, 2);
		for (int i = 1; i <= n; ++i) P[B[i].id].ry = B[i].ans;
		
		int cnt = 0;
		for (int i = 1; i <= n; ++i) {
			P[i].lx = max(P[i].lx, P[i].ly);
				P[i].rx = min(P[i].rx, P[i].ry);
			if (P[i].lx >= P[i].rx) continue;
			H[++cnt] = (hahaha) {1, i, 0, P[i].lx, 1};
			H[++cnt] = (hahaha) {1, i, 0, P[i].rx, -1};
		}
		for (int i = 1; i <= m; ++i)
			if (Q[i].op == 3)
				H[++cnt] = (hahaha) {2, Q[i].l, Q[i].r, i, 0};
		
		stable_sort(H + 1, H + cnt + 1);
		
		for (int i = 1; i <= cnt; ++i)
			if (H[i].type == 1)	add(H[i].l, H[i].delta);
			else printf("%d\n", query(H[i].r) - query(H[i].l - 1));
	}
	return 0;
}
posted @ 2017-03-01 20:04  abclzr  阅读(279)  评论(0编辑  收藏  举报