典型的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;
}