Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 2544 Solved: 1482
Description
Input
Output
Sample Input
Sample Output
1
2
HINT
题解:
发现权值比较小,于是直接二维树状数组,这是我第一次写二维树状数组,好神奇啊就是多了一个for循环而已,直接就可以维护前缀区间了,真是666,没有学过二维树状数组的朋友看代码之后一定可以懂的
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int C[111][333][333], mp[333][333], n, m, q;
inline int lowbit( int x ){ return x & ( -x ); }
void modify( int x, int y, int c, int val ) {
for( register int i = x; i <= n; i += lowbit(i) )
for( register int j = y; j <= m; j += lowbit(j) )
C[c][i][j] += val;
}
int query( int x, int y, int c ) {
int tmp = 0;
for( register int i = x; i ; i -= lowbit(i) )
for( register int j = y; j ; j -= lowbit(j) )
tmp += C[c][i][j];
return tmp;
}
int main( ) {
scanf( "%d%d", &n, &m );
for( register int i = 1; i <= n; i++ )
for( register int j = 1; j <= m; j++ ) {
scanf( "%d", &mp[i][j] );
modify( i, j, mp[i][j], 1 );
}
scanf( "%d", &q );
for( register int i = 1; i <= q; i++ ) { int opt, x1, y1, x2, y2, c;
scanf( "%d", &opt );
if( opt == 1 ) {
scanf( "%d%d%d", &x1, &y1, &c );
modify( x1, y1, mp[x1][y1], -1 );
mp[x1][y1] = c;
modify( x1, y1, mp[x1][y1], 1 );
} else {
scanf( "%d%d%d%d%d", &x1, &x2, &y1, &y2, &c );
int ans = 0;
ans = query( x2, y2, c ) + query( x1 - 1, y1 - 1, c );
ans -= query( x1 - 1, y2, c );
ans -= query( x2, y1 - 1, c );
printf( "%d\n", ans );
}
}
return 0;
}