A rectangle of three colors: Red, green, and blue. When some elements overlap, they are combined into their own colors.
Solution: consider that there are only two colors AB, then calculate the area of the color rectangle and the area of the x, B color rectangle and the area of the y, AB color rectangle and z, then the final, the area of the AB color is x + y-z, and the area of the color is x-(x + y-z ), the area of B color is y-(x + y-z );
Similarly, consider three colors:
According to the formula, first obtain the area x of the three colors, and then consider only two colors in sequence. Then, calculate RG, RB, GB, and subtract x, obtain the mixed area of the two colors, and then obtain the area of only one color.
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<map>using namespace std;const int maxn = 20010;int hash[maxn];struct node { int left, right, key; long long sum; void init(int l, int r) { left = l; right = r; key=0; sum=0; } int mid() { return (left + right) >> 1; } int length() { return hash[right+1] - hash[left]; }};struct SegTree { node tree[maxn * 4]; void init(int l, int r, int idx) { tree[idx].init(l, r); if (l == r) return; int mid = tree[idx].mid(); init(l, mid, idx << 1); init(mid + 1, r, (idx << 1) | 1); } void pushup(int idx) { if (tree[idx].key > 0) tree[idx].sum=tree[idx].length(); else { if (tree[idx].left == tree[idx].right) tree[idx].sum = 0; else tree[idx].sum = tree[idx << 1].sum + tree[(idx << 1) | 1].sum; } } void update(int left, int right, int idx, int v) { if (tree[idx].left >= left && tree[idx].right <= right) { tree[idx].key += v; pushup(idx); return; } int mid = tree[idx].mid(); if (left <= mid) update(left, right, idx << 1, v); if (right > mid) update(left, right, (idx << 1) | 1, v); pushup(idx); }};struct edge { int type, color; int s, t, x; void init(int c, int x, int s, int t, int type) { color = c; this->x = x; this->s = s; this->t = t; this->type = type; } bool operator <(const edge oth) const { return x < oth.x || (x == oth.x && type > oth.type); }};SegTree st;edge ed[maxn];map<int, int> mp;int n, cnt;void init() { mp.clear(); int a, b, c, d, k; char ch[10]; scanf("%d",&n); for (int i = 1; i <= n; i++) { scanf("%s%d%d%d%d", ch, &a, &b, &c, &d); if (ch[0] == 'R') k = 0; else if (ch[0] == 'G') k = 1; else k = 2; ed[i].init(k, a, b, d, 1); ed[n + i].init(k, c, b, d, -1); mp[b] = 0; mp[d] = 0; } sort(ed + 1, ed + n * 2 + 1); cnt = 0; for (map<int, int>::iterator it = mp.begin(); it != mp.end(); it++){ (*it).second = ++cnt; hash[cnt]=(*it).first; }}bool flag[3];void set(int a, int b, int c) { flag[0] = a; flag[1] = b; flag[2] = c;}long long get() { long long ans = 0; st.init(1, cnt - 1, 1); int i = 1; while (i<=2*n&&!flag[ed[i].color]) i++; if(i>2*n) return 0; st.update(mp[ed[i].s], mp[ed[i].t] - 1, 1, ed[i].type); int pre=ed[i].x; i++; for (; i <= n * 2; i++) { if (!flag[ed[i].color]) continue; ans += st.tree[1].sum * (ed[i].x - pre); pre=ed[i].x; st.update(mp[ed[i].s], mp[ed[i].t] - 1, 1, ed[i].type); } return ans;}long long ans[10];//R G B RG RB GB RGBvoid work() { set(1, 0, 0); ans[1] = get();//R set(0, 1, 0); ans[2] = get();//G set(0, 0, 1); ans[3] = get();//B set(1, 1, 1); long long all = get(); set(1, 1, 0); long long ab = ans[1] + ans[2] - get(); set(1, 0, 1); long long ac = ans[1] + ans[3] - get(); set(0, 1, 1); long long bc = ans[3] + ans[2] - get(); ans[7]=all-ans[1]-ans[2]-ans[3]+ab+ac+bc; ans[4]=ab-ans[7]; ans[5]=ac-ans[7]; ans[6]=bc-ans[7]; ans[1]=ans[1]-ans[4]-ans[5]-ans[7]; ans[2]=ans[2]-ans[4]-ans[6]-ans[7]; ans[3]=ans[3]-ans[5]-ans[6]-ans[7];}int main() { int cas; scanf("%d",&cas); for(int c=1;c<=cas;c++){ init(); work(); printf("Case %d:\n",c); for(int i=1;i<=7;i++) printf("%I64d\n",ans[i]); } return 0;}