传送门:【COGS】451 布匠问题
题目分析:这题一看就是二维线段树区间修改区间查询啊,可是。。。写了一下午还是写不出来。。。后来索性暴力1000棵线段树,然后T了三组数据。。。感觉没治了。。。
后来突然想到是不是可以写四分树(四个儿子的线段树),每一个儿子都是一个矩阵,叶子节点就是1X1的矩阵,然后就这么YY了个写法写了下,然后让我十分无语的是:我竟然AC了。。。。。竟然AC了!
迫不及待的想去仰慕大神们的写法(AC了一题以后可以看其他人AC这题的代码),然后更让我无语的是!他们全部是暴力的!!!各种暴力无节操啊有木有!!
我的眼泪忍不住就哗哗哗的流啊T U T。。。
代码如下:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define REP( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i )
#define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i )
#define REV( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )
#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )
#define s1 o * 4 + 1
#define s2 o * 4 + 2
#define s3 o * 4 + 3
#define s4 o * 4 + 4
#define son1 s1 , lx , mx , ly , my
#define son2 s2 , lx , mx , my + 1 , ry
#define son3 s3 , mx + 1 , rx , ly , my
#define son4 s4 , mx + 1 , rx , my + 1 , ry
#define root 0 , 1 , n , 1 , m
#define rt o , lx , rx , ly , ry
#define xxyy x1 , x2 , y1 , y2
const int MAXN = 5000005 ;
int sum[MAXN] ;
int set[MAXN] ;
void pushdown ( int o , int lx , int rx , int ly , int ry ) {
if ( ~set[o] ) {
int mx = ( lx + rx ) >> 1 , my = ( ly + ry ) >> 1 ;
set[s1] = set[o] , sum[s1] = set[o] ? ( mx - lx + 1 ) * ( my - ly + 1 ) : 0 ;
set[s2] = set[o] , sum[s2] = set[o] ? ( mx - lx + 1 ) * ( ry - my ) : 0 ;
set[s3] = set[o] , sum[s3] = set[o] ? ( rx - mx ) * ( my - ly + 1 ) : 0 ;
set[s4] = set[o] , sum[s4] = set[o] ? ( rx - mx ) * ( ry - my ) : 0 ;
set[o] = -1 ;
}
}
void update ( int v , int x1 , int x2 , int y1 , int y2 , int o , int lx , int rx , int ly , int ry ) {
if ( x1 <= lx && rx <= x2 && y1 <= ly && ry <= y2 ) {
set[o] = v ;
sum[o] = v ? ( rx - lx + 1 ) * ( ry - ly + 1 ) : 0 ;
return ;
}
pushdown ( rt ) ;
int mx = ( lx + rx ) >> 1 , my = ( ly + ry ) >> 1 ;
if ( x1 <= mx && y1 <= my ) update ( v , xxyy , son1 ) ;
if ( x1 <= mx && my < y2 ) update ( v , xxyy , son2 ) ;
if ( mx < x2 && y1 <= my ) update ( v , xxyy , son3 ) ;
if ( mx < x2 && my < y2 ) update ( v , xxyy , son4 ) ;
sum[o] = sum[s1] + sum[s2] + sum[s3] + sum[s4] ;
}
int query ( int x1 , int x2 , int y1 , int y2 , int o , int lx , int rx , int ly , int ry ) {
if ( x1 <= lx && rx <= x2 && y1 <= ly && ry <= y2 ) return sum[o] ;
pushdown ( rt ) ;
int mx = ( lx + rx ) >> 1 , my = ( ly + ry ) >> 1 , ans = 0 ;
if ( x1 <= mx && y1 <= my ) ans += query ( xxyy , son1 ) ;
if ( x1 <= mx && my < y2 ) ans += query ( xxyy , son2 ) ;
if ( mx < x2 && y1 <= my ) ans += query ( xxyy , son3 ) ;
if ( mx < x2 && my < y2 ) ans += query ( xxyy , son4 ) ;
return ans ;
}
void scanf ( int& x , char c = 0 ) {
while ( ( c = getchar () ) < '0' || c > '9' ) ;
x = c - '0' ;
while ( ( c = getchar () ) >= '0' && c <= '9' ) x = x * 10 + c - '0' ;
}
void solve () {
int n , m , q ;
int op , x1 , x2 , y1 , y2 ;
scanf ( "%d%d%d" , &n , &m , &q ) ;
CLR ( sum , 0 ) ;
CLR ( set , -1 ) ;
while ( q -- ) {
scanf ( op ) , scanf ( x1 ) , scanf ( y1 ) , scanf ( x2 ) , scanf ( y2 ) ;
//printf ( "ok\n" ) ;
if ( op == 0 ) {
printf ( "%d\n" , query ( xxyy , root ) ) ;
} else update ( 2 - op , xxyy , root ) ;
//printf ( "ok\n" ) ;
}
}
int main () {
freopen ( "fabric.in" , "r" , stdin ) ;
freopen ( "fabric.out" , "w" , stdout ) ;
solve () ;
return 0 ;
}