[HDU 4419] Colourful Rectangle (扫描线 矩形面积并)

时间:2021-03-31 00:42:13

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419

题目大意:比矩形面积并多了颜色,问染成的每种颜色的面积。

矩形面积并的扫描线维护的是长度,这道题就是维护每个颜色的长度,写起来很蛋疼。

 #include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
typedef pair<int,int> PII;
typedef long long LL; struct Node{
int l,r,h,d,c;
bool operator<(const Node& a) const{
return h<a.h;
}
Node(int L=,int R=,int H=,int D=,int C=):l(L),r(R),h(H),d(D),c(C){}
};
const int MAX_N = ;
int T,n;
Node t[MAX_N<<];
int dsum[MAX_N<<][],b[MAX_N<<];
LL sum[];
int scol[MAX_N<<],len[MAX_N<<][]; void push_up(int idx,int l,int r){
int state = (dsum[idx][]>?:)|(dsum[idx][]>?:)|(dsum[idx][]>?:);
if( state ) {
memset(len[idx],,sizeof(len[idx]));
len[idx][state] = b[r+] - b[l];
for(int i=;i<;i++){
if( state!=(state|i) ){
int tmp = len[idx<<][i]+len[idx<<|][i];
len[idx][state|i] += tmp;
len[idx][state] -= tmp;
}
}
} else if(l!=r){
for(int i=;i<;i++){
len[idx][i] = len[idx<<][i] + len[idx<<|][i];
}
} else {
memset(len[idx],,sizeof(len[idx]));
}
} void update(int L,int R,int x,int c,int idx,int l,int r){
if( L<=l&&R>=r ){
dsum[idx][c] += x;
} else {
int m = l+r>>;
if( L<=m ) update(L,R,x,c,idx<<,l,m);
if( R>m ) update(L,R,x,c,idx<<|,m+,r);
}
push_up(idx,l,r);
} int main(){
scanf("%d",&T);
int kase = ;
while(T--){
memset(dsum,,sizeof(dsum));
memset(len,,sizeof(len));
memset(scol,,sizeof(scol));
scanf("%d",&n);
char col[];
int x1,y1,x2,y2;
int ptr = , ptrb = ;
for(int i=;i<n;i++){
scanf("%s%d%d%d%d",col,&x1,&y1,&x2,&y2);
int cc;
if( col[]=='R' ) cc=;
else if( col[]=='G' ) cc = ;
else if( col[]=='B' ) cc = ;
t[ptr++] = Node(x1,x2,y1,,cc);
t[ptr++] = Node(x1,x2,y2,-,cc);
b[ptrb++] = x1;
b[ptrb++] = x2;
}
sort(t,t+ptr);
sort(b,b+ptrb);
int ub = unique(b,b+ptrb) - b;
memset(sum,,sizeof(sum)); for(int i=;i<ptr-;i++){
int l = lower_bound(b,b+ub,t[i].l) - b;
int r = lower_bound(b,b+ub,t[i].r) - b - ;
update(l,r,t[i].d,t[i].c,,,ub-);
if( t[i].h!=t[i+].h ){
for(int j=;j<;j++){
sum[j] += (LL)(t[i+].h-t[i].h)*(LL)(len[][j]);
}
}
}
printf("Case %d:\n",kase++);
printf("%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n",sum[],sum[],sum[],sum[],sum[],sum[],sum[]);
}
return ;
}