HDU-4419-Colourful Rectangle(线段树)

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)

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

Source

2012 ACM/ICPC Asia Regional Hangzhou Online

思路:维护区间R,G,B三种颜色的数量,更新时判断区间的组合颜色,再考虑与左右儿子的颜色组合的情况。

#include <cstdio>
#include <map>
#include <cmath>
#include <algorithm>
using namespace std;

map<int,int>ii;

struct S{
int r,g,b;
int cr,cg,cb,crg,crb,cgb,crgb;
}node[200000];

struct L{
int pos,l,r,type,flag;

bool operator<(const L &p) const
{
    return pos<p.pos;
}

}line[20005];

int lisan[20005],vv[20005];

void build(int idx,int s,int e)
{
    node[idx].r=node[idx].g=node[idx].b=0;

    node[idx].cr=node[idx].cg=node[idx].cb=node[idx].crg=node[idx].crb=node[idx].cgb=node[idx].crgb=0;

    if(s!=e)
    {
        int mid=(s+e)>>1;

        build(idx<<1,s,mid);
        build(idx<<1|1,mid+1,e);
    }
}

void pop(int idx,int s,int e)
{
    node[idx].cr=0;
    node[idx].cg=0;
    node[idx].cb=0;
    node[idx].crg=0;
    node[idx].crb=0;
    node[idx].cgb=0;
    node[idx].crgb=0;

    if(node[idx].r && node[idx].g && node[idx].b)
    {
        node[idx].crgb+=node[idx<<1].cr+node[idx<<1|1].cr;
        node[idx].crgb+=node[idx<<1].cg+node[idx<<1|1].cg;
        node[idx].crgb+=node[idx<<1].cb+node[idx<<1|1].cb;
        node[idx].crgb+=node[idx<<1].crg+node[idx<<1|1].crg;
        node[idx].crgb+=node[idx<<1].crb+node[idx<<1|1].crb;
        node[idx].crgb+=node[idx<<1].cgb+node[idx<<1|1].cgb;
        node[idx].crgb+=node[idx<<1].crgb+node[idx<<1|1].crgb;

        node[idx].crgb+=vv[e]-vv[s-1]-node[idx].cr-node[idx].cg-node[idx].cb-node[idx].crg-node[idx].crb-node[idx].cgb-node[idx].crgb;
    }

    if(!node[idx].r && node[idx].g && node[idx].b)
    {
        node[idx].crgb+=node[idx<<1].cr+node[idx<<1|1].cr;
        node[idx].cgb+=node[idx<<1].cg+node[idx<<1|1].cg;
        node[idx].cgb+=node[idx<<1].cb+node[idx<<1|1].cb;
        node[idx].crgb+=node[idx<<1].crg+node[idx<<1|1].crg;
        node[idx].crgb+=node[idx<<1].crb+node[idx<<1|1].crb;
        node[idx].cgb+=node[idx<<1].cgb+node[idx<<1|1].cgb;
        node[idx].crgb+=node[idx<<1].crgb+node[idx<<1|1].crgb;

        node[idx].cgb+=vv[e]-vv[s-1]-node[idx].cr-node[idx].cg-node[idx].cb-node[idx].crg-node[idx].crb-node[idx].cgb-node[idx].crgb;
    }

    if(node[idx].r && !node[idx].g && node[idx].b)
    {
        node[idx].crb+=node[idx<<1].cr+node[idx<<1|1].cr;
        node[idx].crgb+=node[idx<<1].cg+node[idx<<1|1].cg;
        node[idx].crb+=node[idx<<1].cb+node[idx<<1|1].cb;
        node[idx].crgb+=node[idx<<1].crg+node[idx<<1|1].crg;
        node[idx].crb+=node[idx<<1].crb+node[idx<<1|1].crb;
        node[idx].crgb+=node[idx<<1].cgb+node[idx<<1|1].cgb;
        node[idx].crgb+=node[idx<<1].crgb+node[idx<<1|1].crgb;

        node[idx].crb+=vv[e]-vv[s-1]-node[idx].cr-node[idx].cg-node[idx].cb-node[idx].crg-node[idx].crb-node[idx].cgb-node[idx].crgb;
    }

    if(node[idx].r && node[idx].g && !node[idx].b)
    {
        node[idx].crg+=node[idx<<1].cr+node[idx<<1|1].cr;
        node[idx].crg+=node[idx<<1].cg+node[idx<<1|1].cg;
        node[idx].crgb+=node[idx<<1].cb+node[idx<<1|1].cb;
        node[idx].crg+=node[idx<<1].crg+node[idx<<1|1].crg;
        node[idx].crgb+=node[idx<<1].crb+node[idx<<1|1].crb;
        node[idx].crgb+=node[idx<<1].cgb+node[idx<<1|1].cgb;
        node[idx].crgb+=node[idx<<1].crgb+node[idx<<1|1].crgb;

        node[idx].crg+=vv[e]-vv[s-1]-node[idx].cr-node[idx].cg-node[idx].cb-node[idx].crg-node[idx].crb-node[idx].cgb-node[idx].crgb;
    }

    if(node[idx].r && !node[idx].g && !node[idx].b)
    {
        node[idx].cr+=node[idx<<1].cr+node[idx<<1|1].cr;
        node[idx].crg+=node[idx<<1].cg+node[idx<<1|1].cg;
        node[idx].crb+=node[idx<<1].cb+node[idx<<1|1].cb;
        node[idx].crg+=node[idx<<1].crg+node[idx<<1|1].crg;
        node[idx].crb+=node[idx<<1].crb+node[idx<<1|1].crb;
        node[idx].crgb+=node[idx<<1].cgb+node[idx<<1|1].cgb;
        node[idx].crgb+=node[idx<<1].crgb+node[idx<<1|1].crgb;

        node[idx].cr+=vv[e]-vv[s-1]-node[idx].cr-node[idx].cg-node[idx].cb-node[idx].crg-node[idx].crb-node[idx].cgb-node[idx].crgb;
    }

    if(!node[idx].r && node[idx].g && !node[idx].b)
    {
        node[idx].crg+=node[idx<<1].cr+node[idx<<1|1].cr;
        node[idx].cg+=node[idx<<1].cg+node[idx<<1|1].cg;
        node[idx].cgb+=node[idx<<1].cb+node[idx<<1|1].cb;
        node[idx].crg+=node[idx<<1].crg+node[idx<<1|1].crg;
        node[idx].crgb+=node[idx<<1].crb+node[idx<<1|1].crb;
        node[idx].cgb+=node[idx<<1].cgb+node[idx<<1|1].cgb;
        node[idx].crgb+=node[idx<<1].crgb+node[idx<<1|1].crgb;

        node[idx].cg+=vv[e]-vv[s-1]-node[idx].cr-node[idx].cg-node[idx].cb-node[idx].crg-node[idx].crb-node[idx].cgb-node[idx].crgb;
    }

    if(!node[idx].r && !node[idx].g && node[idx].b)
    {
        node[idx].crb+=node[idx<<1].cr+node[idx<<1|1].cr;
        node[idx].cgb+=node[idx<<1].cg+node[idx<<1|1].cg;
        node[idx].cb+=node[idx<<1].cb+node[idx<<1|1].cb;
        node[idx].crgb+=node[idx<<1].crg+node[idx<<1|1].crg;
        node[idx].crb+=node[idx<<1].crb+node[idx<<1|1].crb;
        node[idx].cgb+=node[idx<<1].cgb+node[idx<<1|1].cgb;
        node[idx].crgb+=node[idx<<1].crgb+node[idx<<1|1].crgb;

        node[idx].cb+=vv[e]-vv[s-1]-node[idx].cr-node[idx].cg-node[idx].cb-node[idx].crg-node[idx].crb-node[idx].cgb-node[idx].crgb;
    }

    if(!node[idx].r && !node[idx].g && !node[idx].b)//别漏了这个
    {
        node[idx].cr+=node[idx<<1].cr+node[idx<<1|1].cr;
        node[idx].cg+=node[idx<<1].cg+node[idx<<1|1].cg;
        node[idx].cb+=node[idx<<1].cb+node[idx<<1|1].cb;
        node[idx].crg+=node[idx<<1].crg+node[idx<<1|1].crg;
        node[idx].crb+=node[idx<<1].crb+node[idx<<1|1].crb;
        node[idx].cgb+=node[idx<<1].cgb+node[idx<<1|1].cgb;
        node[idx].crgb+=node[idx<<1].crgb+node[idx<<1|1].crgb;
    }
}

void update(int idx,int s,int e,int l,int r,int val,int flag)
{
    if(l==s && r==e)
    {
        switch(val)
        {
            case 1:node[idx].r+=flag;break;
            case 2:node[idx].g+=flag;break;
            case 3:node[idx].b+=flag;break;
        }

        pop(idx,s,e);
    }
    else
    {
        int mid=(s+e)>>1;

        if(r<=mid) update(idx<<1,s,mid,l,r,val,flag);
        else if(l>mid) update(idx<<1|1,mid+1,e,l,r,val,flag);
        else
        {
            update(idx<<1,s,mid,l,mid,val,flag);
            update(idx<<1|1,mid+1,e,mid+1,r,val,flag);
        }

        pop(idx,s,e);
    }
}

int main()
{
    int T,n,i,cnt,x1,y1,x2,y2,num,last,cases=1;
    long long ar,ag,ab,arg,arb,agb,argb;
    char s[5];

    scanf("%d",&T);

    while(T--)
    {
        ii.clear();

        ar=ag=ab=arg=arb=agb=argb=0;

        scanf("%d",&n);

        cnt=0;

        num=0;

        while(n--)
        {
            scanf("%s%d%d%d%d",s,&x1,&y1,&x2,&y2);

            if(!ii[y1]) lisan[num++]=y1,ii[y1]=1;
            if(!ii[y2]) lisan[num++]=y2,ii[y2]=1;

            line[cnt].pos=x1;
            line[cnt].l=y1;
            line[cnt].r=y2;

            line[cnt+1].pos=x2;
            line[cnt+1].l=y1;
            line[cnt+1].r=y2;

            if(s[0]=='R')
            {
                line[cnt].flag=1;
                line[cnt++].type=1;
                line[cnt].flag=-1;
                line[cnt++].type=1;
            }
            else if(s[0]=='G')
            {
                line[cnt].flag=1;
                line[cnt++].type=2;
                line[cnt].flag=-1;
                line[cnt++].type=2;
            }
            else
            {
                line[cnt].flag=1;
                line[cnt++].type=3;
                line[cnt].flag=-1;
                line[cnt++].type=3;
            }
        }

        sort(line,line+cnt);
        sort(lisan,lisan+num);

        for(i=0;i<num;i++)
        {
            ii[lisan[i]]=i+1;
            vv[i]=lisan[i];
        }

        build(1,1,num);

        for(i=0;i<cnt;i++)
        {
            if(i)
            {
                ar+=(long long)(line[i].pos-last)*(node[1].cr);
                ag+=(long long)(line[i].pos-last)*(node[1].cg);
                ab+=(long long)(line[i].pos-last)*(node[1].cb);
                arg+=(long long)(line[i].pos-last)*(node[1].crg);
                arb+=(long long)(line[i].pos-last)*(node[1].crb);
                agb+=(long long)(line[i].pos-last)*(node[1].cgb);
                argb+=(long long)(line[i].pos-last)*(node[1].crgb);
            }

            update(1,1,num,ii[line[i].l],ii[line[i].r]-1,line[i].type,line[i].flag);

            last=line[i].pos;
        }

        printf("Case %d:\n",cases++);

        printf("%I64d\n",ar);
        printf("%I64d\n",ag);
        printf("%I64d\n",ab);
        printf("%I64d\n",arg);
        printf("%I64d\n",arb);
        printf("%I64d\n",agb);
        printf("%I64d\n",argb);
    }
}
时间: 2024-12-18 01:59:06

HDU-4419-Colourful Rectangle(线段树)的相关文章

Hdu 4419 Colourful Rectangle(线段树扫描线)

题目大意: 给出多个不同颜色的矩形,求最后覆盖的颜色的面积. 思路分析: 我是自己手动暴力枚举. 比赛的时候漏了一种情况. RGB 可以从 RG+RB组合来(只是举例,就是说可以从两种颜色组合而来). 然后就只需要维护所有的颜色 用扫描线来判断. #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define MAXN 42222 using name

hdu 4419 Colourful Rectangle

http://acm.hdu.edu.cn/showproblem.php?pid=4419 题意:给出3种颜色,重叠会生成新的颜色,然后有一些矩形,求出每种颜色的面积. 转化为二进制表示颜色:001 R ,010G,100B,011RG,101RB,....111RGB; 在结构体里面加上一个len[8]和cover[8]表示每种颜色所占的长度和在区间的覆盖次数. 1 #include <cstdio> 2 #include <cstring> 3 #include <al

HDU 4419 Colourful Rectangle --离散化+线段树扫描线

题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何维护每种颜色的长度着实让我伤透了脑筋.后来看了一位朋友的题解,才幡然醒悟. 开始想到了用二进制表示颜色,R用001表示,G用010表示,B用100表示.那么就可以用十进制1~7表示7种不同颜色了. 维护 cov[rt][1~3] 表示此区间内3种原色各有多少个, Len[rt][i]表示每种颜色的长

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 题目大意:比矩形面积并多了颜色,问染成的每种颜色的面积. 矩形面积并的扫描线维护的是长度,这道题就是维护每个颜色的长度,写起来很蛋疼. 1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6

HDU 4419 Colourful Rectangle 扫描线

题目链接:点击打开链接 题意:给定由红绿蓝组成的一些矩阵 输出每种颜色对应的面积. 思路: 如果颜色只有一种就是扫描线. 这里先求出包含各类颜色的面积,然后容斥一下得到答案. 画个图就能快速得到答案了 #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <queue> #include <set> #inclu

hdu 2795 Billboard(线段树)

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 10890    Accepted Submission(s): 4827 Problem Description At the entrance to the university, there is a huge rectangular billboard of

HDU 4902 Nice boat(线段树)

HDU Nice boat 题目链接 题意:给定一个序列,两种操作,把一段变成x,把一段每个数字,如果他大于x,就变成他和x的gcd,求变换完后,最后的序列. 思路:线段树,每个结点多一个cover表示该位置以下区间是否数字全相同,然后每次延迟操作,最后输出的时候单点查询即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1

hdu 3016 Man Down (线段树 + dp)

题目大意: 是男人就下一般层...没什么可以多说的吧. 注意只能垂直下落. 思路分析: 后面求最大值的过程很容易想到是一个dp的过程 . 因为每一个plane 都只能从左边 从右边下两种状态. 然后我们所需要处理的问题就是 ,你如何能快速知道往左边下到哪里,往右边下到哪里. 这就是线段树的预处理. 讲线段按照高度排序. 然后按照高度从小到大加入到树中. 然后去寻找左端点 和 右端点最近覆盖的线段的编号. #include <cstdio> #include <iostream> #

HDU 3954 Level up 线段树

---NotOnlySuccess 出的题--- 看了题之后觉得和HDU 4027有点像,给的K很小,只有10,目测只要有人升级的时候直接更新到叶子节点就ok了.不过不同于HDU 4027 的是,那题每一次更新都相当于这题的一次升级操作,这题里面可能会出现一次操作之后没有升级和出现升级两种情况,一时半会没了思路. 无奈去搜题解,发现我只要维护一个区间当中距离升级最近的人所需要的基础升级经验,即不算等级加成的裸的升级经验,如果在一次涨经验之后,出现当前区间当中有人会升级,直接将每一个要升级的人更新

多校训练hdu --Nice boat(线段树,都是泪)

Nice boat Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 47 Accepted Submission(s): 10 Problem Description There is an old country and the king fell in love with a devil. The devil always ask