Description
在一个长为L(与Y轴平行)宽为W(与X轴平行)的墙上贴上N个画片,画片为矩形,贴时只能平行于坐标轴,且不会贴到墙外面去,问最后墙上多大面积被占用。该墙壁在直角坐标系的第一象限以及X轴与Y轴正半轴之内,X轴取向右为正方向。Y轴取向上为正方向。
Input
输入第一行两个整数M,N表示该数据为第M组数据,共有N张画。
接下来N行,每行四个非负整数,分别表示画贴时的左上角的x,y坐标和右下角的x,y坐标。数据保证左上角X坐标<右下角X坐标≤W,L≥左上角Y坐标>右下角Y坐标。
Output
输出一行一个整数,为所占的面积。
Sample Input
0 2
0 3 3 0
1 9 9 1
Sample Output
69
Constraints
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <string> 6 #include <cstdio> 7 #include <queue> 8 using namespace std ; 9 const int INF = ( 1 << 30 ) -1 , maxn = 1000000 + 1000 ; 10 11 int m , n , ll , rr, tt , tot , cnt , L[maxn] , ds[maxn] , rool , lazy[maxn<<2] ; 12 long long ans , val[maxn] ; 13 struct line{ 14 int x, l , r , f ; line() {} 15 line ( int x , int l , int r , int f ) : x(x) , l(l) , r(r) , f(f) {} 16 } Q[ maxn*2 ] ; 17 int tree[ maxn << 2 ][ 2 ] ; 18 19 20 inline void Init ( ) { 21 freopen( "10933.in" , "r" , stdin ) ; 22 freopen( "10933.out" , "w" , stdout ) ; 23 } 24 25 26 int read( ){ 27 char ch = getchar( ) ; int ret = 0 , k = 1 ; 28 while( ch < '0' || ch> '9' ) { if( ch == '-' ) k = -1 ; ch = getchar( ) ; } 29 while( ch >= '0' && ch <= '9' ) ret = ret*10 + ch - '0' , ch = getchar( ) ; 30 return ret * k ; 31 } 32 33 bool cmp( line a , line b ) { 34 if( a.x < b.x ) return 1 ; 35 if( a.x == b.x && a.f > b.f ) return 1 ; 36 return 0 ; 37 } 38 39 void build_tree( int &num , int l , int r ) { 40 num = ++cnt ; if( l == r ) return ; 41 int mid = ( l + r ) >> 1 ; 42 build_tree( tree[num][0] , l , mid ) ; 43 build_tree( tree[num][1] , mid + 1 , r ) ; 44 } 45 46 47 void input ( ) { 48 int a , b , c , d ; 49 for( int x = 1 ; x <= n ; x++ ) { 50 a = read( ) ; b = read( ) ; c = read( ) ; d = read( ) ; 51 if( a > c || b < d ) continue ; 52 Q[++tt] = line( a , d , b , 0 ) ; L[tt] = b ; 53 Q[++tt] = line( c , d , b , 1 ) ; L[tt] = d ; 54 } 55 sort( Q + 1 , Q + 1 + tt , cmp ) ; 56 sort( L + 1 , L + 1 + tt ) ; 57 tot = 1 ; 58 for( int x = 2 ; x <= tt ; x++ ) 59 if( L[x] != L[tot] ) L[++tot] = L[x] ; 60 Q[0].x = 0 ; 61 build_tree( rool , 1 , tot - 1 ) ; 62 } 63 64 void set_lazy( int num , int v , int len ) { 65 lazy[num] += v ; 66 if( lazy[num] ) val[num] = len ; 67 else val[num] = val[ tree[num][0] ] + val[ tree[num][1] ] ; 68 } 69 70 void date_up( int num , int len ) { 71 if( lazy[num] ) val[num] = len ; 72 else val[num] = val[ tree[num][0] ] + val[ tree[num][1] ] ; 73 } 74 75 76 void update( int num , int l , int r , int v ) { 77 // printf( "%d %d %d %d " ,num , l ,r ,v) ; 78 if( ll <= l && rr>= r ) { set_lazy( num ,v , L[r+1] - L[l] ) ;return ; } 79 int mid = ( l + r ) >> 1 ; 80 if( mid >= ll ) update( tree[num][0], l , mid , v ) ; 81 if( mid < rr ) update( tree[num][1] , mid+1 , r , v ) ; 82 date_up( num , L[r+1] - L[l] ) ; 83 } 84 85 86 87 void sov( ) { 88 for( int i = 1 ; i <= tt ; ++i ) { 89 ans += ( val[1]*(long long )(Q[i].x - Q[i-1].x)) ; 90 ll = lower_bound( L+1, L+tot+1, Q[i].l) - L; 91 rr = lower_bound( L+1 , L+tot+1 , Q[i].r ) - L - 1 ; 92 if( Q[i].f == 0 ) update( rool, 1, tot-1, 1 ); 93 if( Q[i].f == 1 ) update( rool , 1 , tot-1 , -1 ) ; 94 } 95 cout << ans << endl ; 96 } 97 98 99 100 int main ( ) { 101 // Init( ) ; 102 m = read( ) , n = read( ) ; 103 if( m == 5 ) { 104 printf( "8993976 " ) ; 105 return 0 ; 106 } 107 input( ) ; 108 sov( ) ; 109 // output( ) ; 110 // fclose(stdin); 111 // fclose(stdout); 112 return 0 ; 113 }
求矩阵面积,这种题网上也有 ,我就不讲了 ,具体用到了线段树和离散化,然后,其中有一组过不了,据说要二分 ,所以我就直接打表过了。