Colourful Rectangle
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1460 Accepted Submission(s): 593
Problem Description
We use Red, Green and Blue to make new colours. See the picture below:
Now give you n rectangles, the colour of them is red or green or blue. You have calculate the area of 7 different colour. (Note: A region may be covered by same colour several times, but it’s final colour depends on the kinds of different colour)
Now give you n rectangles, the colour of them is red or green or blue. You have calculate the area of 7 different colour. (Note: A region may be covered by same colour several times, but it’s final colour depends on the kinds of different colour)
Input
The first line is an integer T(T <= 10), the number of test cases. The first line of each case contains a integer n (0 < n <= 10000), the number of rectangles. Then n lines follows. Each line start with a letter C(R means Red, G means Green, B means Blue) and four integers x1, y1, x2, y2(0 <= x1 < x2 < 10^9, 0 <= y1 < y2 < 10^9), the left-bottom's coordinate and the right-top's coordinate of a rectangle.
Output
For each case, output a line "Case a:", a is the case number starting from 1,then 7 lines, each line contain a integer, the area of each colour. (Note: You should print the areas as the order: R, G, B, RG, RB, GB, RGB).
Sample Input
3 2 R 0 0 2 2 G 1 1 3 3 3 R 0 0 4 4 G 2 0 6 4 B 0 2 6 6 3 G 2 0 3 8 G 1 0 6 1 B 4 2 7 7
Sample Output
Case 1: 3 3 0 1 0 0 0 Case 2: 4 4 12 4 4 4 4 Case 3: 0 12 15 0 0 0 0
题意:给你n个矩形,有R、G、B三种颜色,问你R、G、B、RG、RB、GB、RGB颜色的面积并。
思路:状态压缩一下,R = 1, G = 2,B = 4。那么RG = R | G......,总状态1-7。PushUp的时候,先手求出区间的状态color。然后求出1-7的状态 | color的线段长度。注意:color的状态可以由0状态得到。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <string>
#define INF 1000000
#define eps 1e-8
#define MAXN (20000+10)
#define MAXM (100000+10)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while((a)--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
#pragma comment(linker, "/STACK:102400000,102400000")
#define fi first
#define se second
using namespace std;
struct Tree{
int l, r;
LL sum[8];
int cover[3];
};
Tree tree[MAXN<<2];
void Build(int o, int l, int r)
{
tree[o].l = l; tree[o].r = r;
for(int i = 1; i <= 7; i++) tree[o].sum[i] = 0LL;
for(int i = 0; i <= 2; i++) tree[o].cover[i] = 0;
if(l == r) return ;
int mid = (l + r) >> 1;
Build(lson); Build(rson);
}
int rec[MAXN];
void PushUp(int o)
{
int color = 0;
for(int i = 0; i <= 2; i++) if(tree[o].cover[i])
color |= (1<<i);
CLR(tree[o].sum, 0LL);
for(int i = 1; i <= 7; i++)
tree[o].sum[i|color] += tree[ll].sum[i] + tree[rr].sum[i];
LL total = 1LL * (rec[tree[o].r+1] - rec[tree[o].l]);
for(int i = 1; i <= 7; i++) total -= tree[o].sum[i];
tree[o].sum[color] += total;
}
void Update(int o, int L, int R, int cover, int op)
{
if(tree[o].l == L && tree[o].r == R)
{
tree[o].cover[op] += cover;
PushUp(o);
return ;
}
int mid = (tree[o].l + tree[o].r) >> 1;
if(R <= mid) Update(ll, L, R, cover, op);
else if(L > mid) Update(rr, L, R, cover, op);
else {Update(ll, L, mid, cover, op); Update(rr, mid+1, R, cover, op);}
PushUp(o);
}
struct Node{
int op, x1, x2, y, cover;
};
Node num[MAXN];
bool cmp(Node a, Node b){
return a.y < b.y;
}
int get(char op)
{
if(op == 'R') return 0;
if(op == 'G') return 1;
return 2;
}
LL ans[8];
int main()
{
int t, kcase = 1; Ri(t);
W(t)
{
int n; Ri(n); int top = 0;
for(int i = 0; i < n; i++)
{
int x1, y1, x2, y2;
char str[10]; Rs(str);
Ri(x1); Ri(y1); Ri(x2); Ri(y2);
num[top].x1 = x1; num[top].x2 = x2;
num[top].y = y1; num[top].cover = 1;
num[top].op = get(str[0]); rec[top++] = x1;
num[top].x1 = x1; num[top].x2 = x2;
num[top].y = y2; num[top].cover = -1;
num[top].op = get(str[0]); rec[top++] = x2;
}
sort(num, num+top, cmp); sort(rec, rec+top);
int N = unique(rec, rec+top) - rec;
Build(1, 0, N-1); CLR(ans, 0LL);
int l = lower_bound(rec, rec+N, num[0].x1) - rec;
int r = lower_bound(rec, rec+N, num[0].x2) - rec;
Update(1, l, r-1, num[0].cover, num[0].op);
for(int i = 1; i < top; i++)
{
l = lower_bound(rec, rec+N, num[i].x1) - rec;
r = lower_bound(rec, rec+N, num[i].x2) - rec;
for(int j = 1; j <= 7; j++)
ans[j] += tree[1].sum[j] * (num[i].y - num[i-1].y);
if(l <= r-1) Update(1, l, r-1, num[i].cover, num[i].op);
}
printf("Case %d:\n", kcase++); swap(ans[3], ans[4]);
for(int i = 1; i <= 7; i++) Pl(ans[i]);
}
return 0;
}