1. 程式人生 > >【COGS】1577 [OIBH 練習賽#6]戰地統計系統 四分樹

【COGS】1577 [OIBH 練習賽#6]戰地統計系統 四分樹

題目分析:赤果果的四分樹哦~,題目分析就不說了,大家看到一定都會,但是我要吐嘈一下資料= =,這題目的資料竟然有一組是錯誤的!x1 <= x2 沒滿足且0 < v也沒有滿足。。這樣真的大丈夫?

程式碼如下:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;

#define REP( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define REV( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#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 Lower_Left s1 , lx , mx , ly , my
#define Upper_Left s2 , lx , mx , my + 1 , ry
#define Lower_Right s3 , mx + 1 , rx , ly , my
#define Upper_Right s4 , mx + 1 , rx , my + 1 , ry
#define midx ( ( lx + rx ) >> 1 )
#define midy ( ( ly + ry ) >> 1 )
#define root 0 , 1 , n , 1 , 1000

const int MAXN = 2000005 ;

bool set[MAXN] ;
int sum[MAXN] , area[MAXN] , add[MAXN] ;
int n , m ;
int Lx , Rx , Ly , Ry ;

void pushdown ( int o ) {
	if ( set[o] ) {
		set[s1] = set[s2] = set[s3] = set[s4] = 1 ;
		sum[s1] = sum[s2] = sum[s3] = sum[s4] = 0 ;
		add[s1] = add[s2] = add[s3] = add[s4] = 0 ;
		set[o] = 0 ;
	}
	if ( add[o] ) {
		sum[s1] += area[s1] * add[o] ;
		sum[s2] += area[s2] * add[o] ;
		sum[s3] += area[s3] * add[o] ;
		sum[s4] += area[s4] * add[o] ;
		add[s1] += add[o] ;
		add[s2] += add[o] ;
		add[s3] += add[o] ;
		add[s4] += add[o] ;
		add[o] = 0 ;
	}
}

void build ( int o , int lx , int rx , int ly , int ry ) {
	sum[o] = add[o] = set[o] = 0 ;
	area[o] = ( rx - lx + 1 ) * ( ry - ly + 1 ) ;
	if ( lx == rx && ly == ry ) return ;
	area[s1] = area[s2] = area[s3] = area[s4] = 0 ;
	int mx = midx , my = midy ;
	if ( lx <= mx && ly <= my ) build ( Lower_Left ) ;
	if ( lx <= mx && my <  ry ) build ( Upper_Left ) ;
	if ( mx <  rx && ly <= my ) build ( Lower_Right ) ;
	if ( mx <  rx && my <  ry ) build ( Upper_Right ) ;
}

void update ( int op , int o , int lx , int rx , int ly , int ry ) {
	if ( Lx <= lx && rx <= Rx && Ly <= ly && ry <= Ry ) {
		if ( op ) {
			set[o] = 1 ;
			add[o] = sum[o] = 0 ;
		} else {
			add[o] ++ ;
			sum[o] += area[o] ;
		}
		return ;
	}
	pushdown ( o ) ;
	int mx = midx , my = midy ;
	if ( Lx <= mx && Ly <= my ) update ( op , Lower_Left ) ;
	if ( Lx <= mx && my <  Ry ) update ( op , Upper_Left ) ;
	if ( mx <  Rx && Ly <= my ) update ( op , Lower_Right ) ;
	if ( mx <  Rx && my <  Ry ) update ( op , Upper_Right ) ;
	sum[o] = sum[s1] + sum[s2] + sum[s3] + sum[s4] ;
}

int query ( int o , int lx , int rx , int ly , int ry ) {
	if ( Lx <= lx && rx <= Rx && Ly <= ly && ry <= Ry ) return sum[o] ;
	pushdown ( o ) ;
	int mx = midx , my = midy , ans = 0 ;
	if ( Lx <= mx && Ly <= my ) ans += query ( Lower_Left ) ;
	if ( Lx <= mx && my <  Ry ) ans += query ( Upper_Left ) ;
	if ( mx <  Rx && Ly <= my ) ans += query ( Lower_Right ) ;
	if ( mx <  Rx && my <  Ry ) ans += query ( Upper_Right ) ;
	return ans ;
}

void solve () {
	int k ;
	Ly = 1 ;
	scanf ( "%d%d" , &n , &m ) ;
	build ( root ) ;
	while ( m -- ) {
		scanf ( "%d%d%d%d" , &k , &Lx , &Rx , &Ry ) ;
		if ( !Ry || Rx < Lx ) printf ( "0\n" ) ;//資料錯了,所以加這句話才能AC...
		else if ( k == 1 ) update ( 0 , root ) ;
		else {
			printf ( "%d\n" , query ( root ) ) ;
			update ( 1 , root ) ;
		}
	}
}

int main () {
	freopen ( "battlefieldstat.in" , "r" , stdin ) ;
	freopen ( "battlefieldstat.out" , "w" , stdout ) ;
	solve () ;
	return 0 ;
}