把题面改下风格:
有 n*m 个点, 每个点 i 有权值 xi,yi,zi, 要求回答 q 次询问, 每次给定 l1, r1,l2, r2,l3,查询有多少点满足:
-
l1 ≤ xi ≤ r1
-
l2 ≤ yi ≤ r2
-
l3 = zi
说是三维 log3 的查询, 但直接开 z 个二维树状数组, log 方也行。
#include<bits/stdc++.h>
using namespace std;
const int N = 303;
int n, m, a[N][N];
struct BIT {
int t[N][N];
BIT() {
memset(t, 0, sizeof t);
}
void ins(int x, int y, int v) {
int tmp = y;
for(; x<=n; x+=(x&(-x))) {
y = tmp;
for(; y<=m; y+=(y&(-y)))
t[x][y] += v;
}
}
int ask_(int x, int y) {
int res = 0, tmp = y;;
for(; x; x-=(x&(-x))) {
y = tmp;
for(; y; y-=(y&(-y)))
res += t[x][y];
}
return res;
}
int ask(int lx, int rx, int ly, int ry) {
return ask_(rx, ry) - ask_(rx, ly-1) - ask_(lx-1, ry) + ask_(lx-1, ly-1);
}
} T[103];
int main() {
scanf("%d%d", &n, &m);
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
{
scanf("%d", &a[i][j]);
T[a[i][j]].ins(i, j, 1);
}
// for(int i=1; i<=n; ++i, cout<<'
')
// for(int j=1; j<=m; ++j) cout << T[a[i][j]].ask(i, i, j, j) << ' ';
// cout << "# " << T[2].ask_(3, 3) << '
';
int Q;
scanf("%d", &Q);
while(Q--)
{
int op;
scanf("%d", &op);
if(op == 1)
{
int x, y, c;
scanf("%d%d%d", &x, &y, &c);
T[a[x][y]].ins(x, y, -1);
T[a[x][y] = c].ins(x, y, 1);
}
if(op == 2)
{
int lx, rx, ly, ry, c;
scanf("%d%d%d%d%d", &lx, &rx, &ly, &ry, &c);
cout << T[c].ask(lx, rx, ly, ry) << '
';
}
}
return 0;
}