【BZOJ1062】[NOI2008]糖果雨【二维树状数组】

【题目链接】

神题。

【别人的题解】

/* Pigonometry */
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 2005, maxm = 4005, maxc = 1000005;

int len, len2, len4, tr[2][maxn][maxm];

inline int iread() {
	int f = 1, x = 0; char ch = getchar();
	for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return f * x;
}

inline void add(int k, int x, int y, int c) {
	x++; y++;
	for(int i = x; i <= len2; i += i & -i) for(int j = y; j <= len4; j += j & -j)
		tr[k][i][j] += c;
}

inline int sum(int k, int x, int y) {
	if(x < 0 || y < 0) return 0;
	x++; y++;
	int ans = 0;
	if(x > len2) x = len2 + 1;
	if(y > len4) y = len4 + 1;
	for(int i = x; i; i -= i & -i) for(int j = y; j; j -= j & -j)
		ans += tr[k][i][j];
	return ans;
} 

inline int sum(int k, int x1, int y1, int x2, int y2) {
	return sum(k, x2, y2) + sum(k, x1 - 1, y1 - 1) - sum(k, x1 - 1, y2) - sum(k, x2, y1 - 1);
}

int x[maxc], y[maxc];

int main() {
	int T = iread(); len = iread(); len2 = len << 1; len4 = len2 << 1;
	while(T--) {
		int opt = iread();
		if(opt == 1) {
			int t = iread(), c = iread(), l = iread(), r = iread(), d = iread();
			x[c] = (t - d * l + len2) % len2;
			y[c] = r - l;
			add(0, x[c], y[c] + x[c], 1);
			add(1, x[c], y[c] - x[c] + len2, 1);
		}
		else if(opt == 2) {
			int t = iread(), l = iread(), r = iread();
			t %= len2;
			int k = r == len;
			int ans = sum(0, t, l + t, r + t, len4) + sum(0, 0, l + t - len2, r + t - len2 - k, len4)
					+ sum(1, t - r + len2 + k, l - t, len2, len4) + sum(1, t - r, l - t + len2, t - 1, len4);
			printf("%d\n", ans);
		}
		else if(opt == 3) {
			int t = iread(), c = iread();
			add(0, x[c], y[c] + x[c], -1);
			add(1, x[c], y[c] - x[c] + len2, -1);
		}
	}
	return 0;
}


你可能感兴趣的:(【BZOJ1062】[NOI2008]糖果雨【二维树状数组】)