hdu 4419 Colourful Rectangle (2012杭州区域赛 1010 )

来源:互联网 发布:免root备份软件 编辑:程序博客网 时间:2024/05/23 01:09

扫描  + 线段树;

首先离散化y, 节点用二进制保存7种颜色的个数, 


#include<iostream>#include<stdio.h>#include<cstring>#include<algorithm>using namespace std;#define M 20010struct Line{int up, down, x, left, col;Line(){}Line( int a, int b, int c, int d, int e):x(a), down(b), up(c), left(d), col(e){}bool operator < ( const Line &a ) const{return x < a.x;}}line[M];int Y[M], cnt;long long ans[8];struct Node{int l, r, col[8], v[4];int mid() { return (l+r)>>1; }}node[M*4];void build(int l, int r, int p ){node[p].l = l; node[p].r = r;memset(node[p].col, 0, sizeof(node[p].col));memset(node[p].v, 0, sizeof(node[p].v));node[p].col[0] = Y[r] - Y[l];    //初始化白色;if( l + 1 == r ) return;int mid = node[p].mid();build(l, mid, p*2);build(mid, r, p*2+1);}void UP( int p ){int res = 0;for( int i = 0; i < 3; i++ ) if( node[p].v[i] )res += (1<<i);                             //当前节点的颜色memset( node[p].col, 0, sizeof(node[p].col) ); //初始化为0,因为当前颜色由子节点的颜色和当前颜色一起决定if( node[p].l + 1 == node[p].r ){           //没有子节点node[p].col[res] = Y[node[p].r] - Y[node[p].l];return;}for( int i = 0; i < 8; i++ ){              //(res|i),表示当前节点的颜色与子节点的颜色重合node[p].col[res|i] += node[p*2].col[i];node[p].col[res|i] += node[p*2+1].col[i];}}void update( int x, int y, int col, int left, int p ){if( x <= node[p].l && y >= node[p].r ){node[p].v[col] += left;UP(p);return;}int mid = node[p].mid();if( mid >= y )update( x, y, col, left, p*2 );else if( mid <= x )update( x, y, col, left, p*2+1 );else{update( x, y, col, left, p*2 );update( x, y, col, left, p*2+1 );}UP( p );}int main(){int T;scanf( "%d", &T );int n, e, tt = 0;int x1, y1, x2, y2, k, i;char c;long long cur, pre, len;while( T-- ){scanf( "%d", &n );memset( ans, 0, sizeof(ans) );cnt = e = 0;for(i = 0; i < n; i++ ){scanf( " %c%d%d%d%d", &c, &x1, &y1, &x2, &y2 );if( c == 'R' ) k = 0;if( c == 'G' ) k = 1;if( c == 'B' ) k = 2;line[e++] = Line( x1, y1, y2, 1, k );line[e++] = Line( x2, y1, y2, -1, k );Y[cnt++] = y1; Y[cnt++] = y2;}sort( Y, Y+cnt );cnt = unique( Y, Y+cnt ) - Y;   //离散化, uinique()是去掉重复的数,返回不相同的数的个数build( 0, cnt-1, 1 );sort(line, line+e);pre = line[0].x;i = 0;while( i < e ){cur = line[i].x;for( int j = 1; j < 8; j++ ){len = node[1].col[j];ans[j] += (cur-pre)*len;}while( line[i].x == cur ){y1 = lower_bound( Y, Y+cnt, line[i].down ) - Y;   //离散化, 返回Y中第一个大于等于line[i].down的下标y2 = lower_bound( Y, Y+cnt, line[i].up ) - Y;update( y1, y2, line[i].col, line[i].left, 1 );i++;}pre = cur;}printf( "Case %d:\n", ++tt );printf( "%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n",ans[1], ans[2], ans[4], ans[3], ans[5], ans[6], ans[7] );}}


原创粉丝点击