hdu 4391

          題目鏈接

  典型的sqrt(n)分塊題目, 不過是個插段問段, 做法還是大同小異。。。。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cstdlib>

using namespace std;

const int sz = 400;

inline int readint() {
	char c = getchar();
	while (!isdigit(c)) c = getchar();

	int x = 0;
	while (isdigit(c)) {
		x = x * 10 + c - '0';
		c = getchar();
	}

	return x;
}

struct Block {
	int A[300][sz + 1], B[300][sz + 1];
	int size[305];
	int lazy[305];
	int n, row;

	void init(int n) {
		this->n = n;
		row = 0;
		memset(size, 0, sizeof(size));
		int r = 0, c = 0;
		for (int i = 0; i < n; i++) {
			scanf("%d", &A[r][c]);
			B[r][c] = A[r][c];
			size[r]++;
			c++;
			if (c == sz) {
				c = 0;
				r++;
			}
		}
		row = r + 1;
		for (int i = 0; i < row; i++) {
			sort(B[i], B[i] + size[i]);
			lazy[i] = -1;
		}
	}

	void modify(int l, int r, int x) {
		int r1 = l / sz, r2 = r / sz;
		int c1 = l % sz, c2 = r % sz;
		
		if (r1 == r2) {
			if (lazy[r1] == -1) {
				while (c1 <= c2) {
					A[r1][c1] = x;
					c1++;
				}
			}
			else {
				fill(A[r1], A[r1] + size[r1], lazy[r1]);
				while (c1 <= c2) {
					A[r1][c1] = x;
					c1++;
				}
				lazy[r1] = -1;	
			}

			copy(A[r1], A[r1] + size[r1], B[r1]);
			sort(B[r1], B[r1] + size[r1]);
		}
		else {
			int tmp = size[r1];

			if (lazy[r1] == -1) {
				while (c1 < tmp) {
					A[r1][c1] = x;
					c1++;
				}
				copy(A[r1], A[r1] + size[r1], B[r1]);
				sort(B[r1], B[r1] + size[r1]);	
			}
			else {					
				fill(A[r1], A[r1] + size[r1], lazy[r1]);
				while (c1 < tmp) {
					A[r1][c1] = x;
					c1++;
				}
				lazy[r1] = -1;	
				copy(A[r1], A[r1] + size[r1], B[r1]);
				sort(B[r1], B[r1] + size[r1]);
			}

			r1++;

			if (lazy[r2] == -1) {
				while (c2 >= 0) {
					A[r2][c2] = x;
					c2--;
				}
				copy(A[r2], A[r2] + size[r2], B[r2]);
				sort(B[r2], B[r2] + size[r2]);
			}
			else {					
				fill(A[r2], A[r2] + size[r2], lazy[r2]);
				while (c2 >= 0) {
					A[r2][c2] = x;
					c2--;
				}
				lazy[r2] = -1;	
				copy(A[r2], A[r2] + size[r2], B[r2]);
				sort(B[r2], B[r2] + size[r2]);
			}

			while (r1 < r2) {
				lazy[r1] = x;
				r1++;
			}
		}
	}

	int query(int l, int r, int x) {
		int r1 = l / sz, r2 = r / sz;
		int c1 = l % sz, c2 = r % sz;
		int res = 0;
		if (r1 == r2) {
			if (lazy[r1] == -1) {					
				while (c1 <= c2) {
					if (A[r1][c1] == x) res++;
					c1++;
				}
			}
			else {
				res += lazy[r1] == x ? c2 - c1 + 1 : 0;
			}
		}
		else {
			int tmp = size[r1];

			if (lazy[r1] == -1) {					
				while (c1 < tmp) {
					if (A[r1][c1] == x) res++;
					c1++;
				}
			}
			else {
				res += lazy[r1] == x ? tmp - c1 : 0;
			}

			r1++;

			if (lazy[r2] == -1) {
				while (c2 >= 0) {
					if (A[r2][c2] == x) res++;
					c2--;
				}	
			}
			else {
				res += lazy[r2] == x ? c2 + 1 : 0;
			}

			while (r1 < r2) {
				if (lazy[r1] == -1)
					res += upper_bound(B[r1], B[r1] + size[r1], x) 
						- lower_bound(B[r1], B[r1] + size[r1], x);
				else
					res += lazy[r1] == x ? size[r1] : 0;
				r1++;	
			}
		}

		return res;
	}
}sol;

int main() {
	int n, m, c, l, r, op;

	while (~scanf("%d%d", &n, &m)) {
		sol.init(n);
		while (m--) {
			//op = readint(), l = readint(), r = readint(), c = readint();
			scanf("%d%d%d%d", &op, &l, &r, &c);
			if (op == 1)
				sol.modify(l, r, c);
			else
				printf("%d\n", sol.query(l, r, c));
		}
	}	

	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章