hdu 4419 Colourful Rectangle 杭州赛区 1010 (解题报告)

杭州赛区最后一题。。。。

最近看线段树还是有收获的·~~~

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>

#define ls rt<<1
#define rs rt<<1|1
#define lson l,m,ls
#define rson m+1,r,rs
#define sf scanf 
#define pf printf
using namespace std;

const int N = 10000 * 2 +10;

//437MS 2512K 3151 B C++ 
/* 
 比赛的时候也想到了容斥原理,但是并没有那么做,而是用cnt[3][rt]记录每种颜色的线
 条有还是没有,结果把自己卡死了。。。。
 比赛后用容斥原理做了一下,好吧,还是容斥原理好做些。
 建立7课线段树,拿矩形覆盖面积模版一套即可求出 R, G, B, RG, RB, GB, RGB 7种颜色
 的面积值sum[],但这个并不是最终答案,画个韦恩图就得出关系了,进而求得are[]。
 注意:sum,are要 __int64 
 */ 
 
int cnt[N<<2];
int len[N<<2];
int tot[10];
__int64 sum[10],are[10];

struct segment{
	int lx,rx,y;
	int kind;
}s[10][N];
 
int x[10][N];
int xcount[10];

bool cmp(segment s1,segment s2){
	return s1.y<s2.y;
}

void pushup(int l,int r,int rt,int k){
	if(cnt[rt])
		len[rt]=x[k][r+1]-x[k][l];
	else if(l==r)
		len[rt]=0;
	else 
		len[rt]=len[ls]+len[rs];
}
void updata(int ql,int qr,int l,int r,int rt,int kind,int k){
    int m=(r+l)>>1;
	if(l==ql && r==qr) cnt[rt]+=kind; 
    else if(qr<=m) updata(ql,qr,lson,kind,k);
	else if(ql>m) updata(ql,qr,rson,kind,k);
	else{
         updata(ql,m,lson,kind,k);
         updata(m+1,qr,rson,kind,k);
    }
	pushup(l,r,rt,k);
}

void input(int a,int x1,int x2,int y1,int y2){
     x[a][tot[a]]=x1; 
     s[a][tot[a]].lx=x1;
     s[a][tot[a]].rx=x2;
     s[a][tot[a]].y=y1;
     s[a][tot[a]].kind=1;
     tot[a]++;
      
     x[a][tot[a]]=x2; 
     s[a][tot[a]].lx=x1;
     s[a][tot[a]].rx=x2;
     s[a][tot[a]].y=y2;
     s[a][tot[a]].kind=-1;
     tot[a]++;
} 

#define test(a,b) for(int ii=0;ii<(b);ii++)printf("%d%c",(a)[ii],ii==(b)-1?'\n':' ') 
#define cntd(a,b) unique((a),(a)+(b))-(a) 
#define lb(a,b,c) lower_bound((a),(a)+(b),(c))-(a) 
#define fill(a) memset( (a),0,sizeof((a)) ); 

int main(){
	int n,tt,col,cas=1;
	scanf("%d",&tt);
	while(tt--){
        scanf("%d",&n);
		fill(tot); 
		fill(sum);
		fill(are);
		for(int i=0;i<n;i++){
            getchar();
            char c;
            int x1,y1,x2,y2;
			scanf("%c%d%d%d%d",&c,&x1,&y1,&x2,&y2);
			if(c=='R') { input(0,x1,x2,y1,y2);  input(3,x1,x2,y1,y2); input(4,x1,x2,y1,y2); input(6,x1,x2,y1,y2); }
			if(c=='G') { input(1,x1,x2,y1,y2);  input(3,x1,x2,y1,y2); input(5,x1,x2,y1,y2); input(6,x1,x2,y1,y2); } 
			if(c=='B') { input(2,x1,x2,y1,y2);  input(4,x1,x2,y1,y2); input(5,x1,x2,y1,y2); input(6,x1,x2,y1,y2); } 
		}
	    //test(tot,7);
                
		for(int i=0;i<7;i++){ 
		    sort(x[i],x[i]+tot[i]);
		    sort(s[i],s[i]+tot[i],cmp);	
	        xcount[i]=cntd(x[i],tot[i])-1;
            fill(cnt);
            fill(len);
		    for(int j=0;j<tot[i]-1;j++){
		    
			    int fx1=lb(x[i],xcount[i],s[i][j].lx);
			    int fx2=lb(x[i],xcount[i],s[i][j].rx)-1;
                //printf("%d %d %d\n",i,fx1,fx2);
			    updata(fx1,fx2,0,xcount[i]-1,1,s[i][j].kind,i);	
                sum[i]+=(__int64)(s[i][j+1].y-s[i][j].y)*len[1];
		    } 
        }
        are[0]=sum[6]-sum[5];
        are[1]=sum[6]-sum[4];
        are[2]=sum[6]-sum[3];
        are[3]=sum[4]-sum[2]-are[0];
        are[4]=sum[5]-sum[1]-are[2];
        are[5]=sum[3]-sum[0]-are[1];
        are[6]=sum[0]-are[0]-are[3]-are[4];
        
		printf("Case %d:\n",cas++);
		for(int i=0;i<7;i++)
		    printf("%I64d\n",are[i]); 
	}
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值