BZOJ 3132: 上帝造题的七分钟( 二维BIT )

二维树状数组...

自己YY一下再推一下应该可以搞出来... 

----------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
 
#define rep( i , n ) for( int i = 0 ; i < n ; ++i )
#define clr( x , c ) memset( x , c , sizeof( x ) )
#define Rep( i , n ) for( int i = 1 ; i <= n ; ++i )
#define lowbit( x ) ( x & -x )
 
using namespace std;
 
const int maxn = 2048 + 5;
 
int a[ maxn ][ maxn ] , b[ maxn ][ maxn ] , c[ maxn ][ maxn ] , d[ maxn ][ maxn ];
int n , m , v;
 
void add( const int x , const int y ) {
if( ! x || ! y ) return;
for( int i = x ; i <= n ; i += lowbit( i ) )
   for( int j = y ; j <= m ; j += lowbit( j ) ) {
       a[ i ][ j ] += v * x;
       b[ i ][ j ] += v * y;
       c[ i ][ j ] += v * x * y;
       d[ i ][ j ] += v;
   }
}
 
int Q( const int x , const int y ) {
if( ! x || ! y ) return 0;
int A , B , C , D;
A = B = C = D = 0;
for( int i = x ; i ; i -= lowbit( i ) )
   for( int j = y ; j ; j -= lowbit( j ) ) {
    A += a[ i ][ j ];
    B += b[ i ][ j ];
    C += c[ i ][ j ];
    D += d[ i ][ j ];
   }
return D * ( x + 1 ) * ( y + 1 ) + C  - A * ( y + 1 ) - B * ( x + 1 );
}
 
int main() {
freopen( "test.in" , "r" , stdin );
clr( a , 0 );
clr( b , 0 );
clr( c , 0 );
clr( d , 0 );
char ch;
int h[ 4 ];
cin >> ch >> n >> m;
while( scanf( " %c" , &ch ) == 1 ) {
rep( i , 4 ) scanf( "%d" , h + i );
h[ 2 ]++ , h[ 3 ]++;
if( ch == 'L' ) {
scanf( "%d" , &v );
add( h[ 2 ] , h[ 3 ] );
add( h[ 0 ] , h[ 1 ] );
v = -v;
add( h[ 0 ] , h[ 3 ] );
add( h[ 2 ] , h[ 1 ] );
} else {
rep( i , 4 ) h[ i ]--;
   printf( "%d\n" , Q( h[ 2 ] , h[ 3 ] ) + Q( h[ 0 ] , h[ 1 ] ) - Q( h[ 0 ] , h[ 3 ] ) - Q( h[ 2 ] , h[ 1 ] ) );
   }
}
return 0;
}

 

----------------------------------------------------------------------------------

3132: 上帝造题的七分钟

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 539  Solved: 252
[Submit][Status][Discuss]

Description

“第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵。

第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作。

第三分钟,k说,要能查询,于是便有了求给定矩形区域内的全部数字和的操作。

第四分钟,彩虹喵说,要基于二叉树的数据结构,于是便有了数据范围。

第五分钟,和雪说,要有耐心,于是便有了时间限制。

第六分钟,吃钢琴男说,要省点事,于是便有了保证运算过程中及最终结果均不超过32位有符号整数类型的表示范围的限制。

第七分钟,这道题终于造完了,然而,造题的神牛们再也不想写这道题的程序了。”

       ——《上帝造裸题的七分钟》

所以这个神圣的任务就交给你了。

Input

 输入数据的第一行为X n m,代表矩阵大小为n×m。

从输入数据的第二行开始到文件尾的每一行会出现以下两种操作:

  L a b c d delta —— 代表将(a,b),(c,d)为顶点的矩形区域内的所有数字加上delta。

  k a b c d   —— 代表求(a,b),(c,d)为顶点的矩形区域内所有数字的和。

 

请注意,k为小写。


        

Output

针对每个k操作,在单独的一行输出答案。

Sample Input

X 4 4
L 1 1 3 3 2
L 2 2 4 4 1
k 2 2 3 3

Sample Output

12

HINT

对于100%的数据,1 ≤ n ≤ 2048, 1 ≤ m ≤ 2048, 1 ≤ abs(delta) ≤ 500,操作不超过200000个,保证运算过程中及最终结果均不超过32位带符号整数类型的表示范围。

Source

 

posted @ 2015-06-27 22:16  JSZX11556  阅读(372)  评论(0编辑  收藏  举报