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

tyvj

时间: 2024-12-06 14:38:46

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

tyvj P1716 - 上帝造题的七分钟 二维树状数组区间查询及修改 二维线段树

P1716 - 上帝造题的七分钟 From Riatre    Normal (OI)总时限:50s    内存限制:128MB    代码长度限制:64KB 背景 Background 裸体就意味着身体. 描述 Description “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵.第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作.第三分钟,k说,要能查询,于是便有了求给定矩形区域内的全部数字和的操作.第

P4514 上帝造题的七分钟——二维树状数组

P4514 上帝造题的七分钟 求的是矩阵里所有数的和: 维护四个树状数组: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=2050; int b[maxn][maxn],bi[maxn][maxn],bj[maxn][maxn],bij[maxn][maxn]; char s[2]; int n,m,num; void add(int

BZOJ 3038 上帝造题的七分钟2 (并查集+树状数组)

题解:同 BZOJ 3211 花神游历各国,需要注意的是需要开long long,还有左右节点需要注意一下. #include <cstdio> #include <cmath> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; LL a[100005],c[100005]; int f[100005],n,m,op,l,r,t; int s

bzoj 3038: 上帝造题的七分钟2 线段树||hdu 4027

3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1066  Solved: 476[Submit][Status][Discuss] Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部."第一分钟,X说,要有数列,于是便给定了一个正整数数列.第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作.第三分钟,k说,要能查询,于是便有了求一段数的和的操作.第四分

BZOJ 3038: 上帝造题的七分钟2【线段树区间开方问题】

3038: 上帝造题的七分钟2 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1469  Solved: 631[Submit][Status][Discuss] Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段数中每个数都开平方(下取整)的操作. 第三分钟,k说,要能查询,于是便有了求一段数的和的操作.

BZOJ 3038 上帝造题的七分钟2 树状数组+并查集

题目大意:一个序列,有两种操作,1.将一段数中的每一个数开根号.2.查询一段数的和. 思路:和3211是一个题,有兴趣的可以看看我的那篇博客. CODE: #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 100010 using namespace std; int cnt,asks

BZOJ 3038 上帝造题的七分钟2

我们发现每个数被开平方的次数不是太多. 然后1开平方还是1. 然后怎么办? 暴力啊!只要找到没有1的地方暴力做就可以了. #include<iostream>#include<cstdio>#include<cstring>#include<cmath>#define maxn 100500using namespace std;long long ls[maxn<<3],rs[maxn<<3],value[maxn<<3

【树状数组】BZOJ3132 上帝造题的七分钟

3132: 上帝造题的七分钟 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1004  Solved: 445[Submit][Status][Discuss] Description "第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作. 第三分钟,k说,要能查询,于是便有了求给定矩形区域内的全部数字和的操作.

二维树状数组的区间加减及查询 tyvj 1716 上帝造题的七分钟

具体解释见小结.http://blog.csdn.net/zmx354/article/details/31740985 #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack>