题目链接

主要是pushup的代码,其他和区间更新+扫描线差不多。

那个区间如果要再刷一层x,那么sum[x][rt] = que[r+1] - que[l];但是如果原本有颜色为i,颜色将会变成i|x,sum[x][rt] 要减去以前的i颜色的部分。sum[i|x][rt]要加上那部分。

这个题还可以用容斥,容斥的话,多次求面积并就可以了,代码直接是模版,对扫描线,还是不熟啊。

 #include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
#define LL __int64
#define maxn 20100
#define lson l , m, rt<<1
#define rson m+1, r,rt<<1|1
int que[*maxn];
int sum[][*maxn];
int cnt[*maxn][];
LL ans[];
struct node
{
int lx,rx,y;
int s;
node() {}
node (int a,int b,int c,int d):lx(a),rx(b),y(c),s(d) {}
bool operator < (const node &S)const
{
return y < S.y;
}
} mat[*maxn];
int bin(int x,int n)
{
int str,end,mid;
str = ;
end = n;
while(str <= end)
{
mid = (str + end)/;
if(que[mid] == x)
return mid;
else if(que[mid] > x)
end = mid - ;
else
str = mid + ;
}
return mid;
}
void pushup(int rt,int l,int r)
{
int i,x,t;
x = ;
for(i = ;i <= ;i ++)
{
if(cnt[rt][i] > )
x |= (<<(i-));
}
if(x)
{
for(i = ;i < ;i ++)
sum[i][rt] = ;
sum[x][rt] = que[r+] - que[l];
for(i = ; i < ; i ++)//注意这里
{
if(x != (i|x))
{
t = sum[i][rt<<] + sum[i][rt<<|];
sum[x|i][rt] += t;
sum[x][rt] -= t;//减去原本的其他颜色
}
}
}
else if(l == r)
{
for(i = ; i < ; i ++)
sum[i][rt] = ;
}
else
{
for(i = ; i < ; i ++)
sum[i][rt] = sum[i][rt<<] + sum[i][rt<<|];
}
}
void update(int L,int R,int c,int l,int r,int rt)
{
int m;
if(l >= L&&r <= R)
{
c > ? cnt[rt][c] ++:cnt[rt][-c] --;
pushup(rt,l,r);
return ;
}
m = (l+r)>>;
if(L <= m)
update(L,R,c,lson);
if(R > m)
update(L,R,c,rson);
pushup(rt,l,r);
}
int main()
{
int n,cas = ,i,j,l,r,t,num;
char ch[];
int a,b,c,d,col;
scanf("%d",&t);
while(t --)
{
scanf("%d",&n);
num = ;
for(i = ; i <= n; i ++)
{
scanf("%s%d%d%d%d",ch,&a,&b,&c,&d);
if(ch[] == 'R')
col = ;
else if(ch[] == 'G')
col = ;
else
col = ;
mat[num] = node(a,c,b,col);
que[num++] = a;
mat[num] = node(a,c,d,-col);
que[num++] = c;
}
sort(que,que+num);
sort(mat,mat+num);
int k = ;
for(i = ; i < num; i ++)
{
if(que[i] != que[i-])
que[k++] = que[i];
}
memset(cnt,,sizeof(cnt));
memset(sum,,sizeof(sum));
memset(ans,,sizeof(ans));
for(i = ; i < num-; i ++)
{
l = bin(mat[i].lx,k-);
r = bin(mat[i].rx,k-) - ;
if(l <= r)
update(l,r,mat[i].s,,k-,);
for(j = ; j < ; j ++)
ans[j] += ((LL)mat[i+].y - (LL)mat[i].y)*(LL)sum[j][];
}
printf("Case %d:\n",cas++);
printf("%I64d\n",ans[]);
printf("%I64d\n",ans[]);
printf("%I64d\n",ans[]);
printf("%I64d\n",ans[]);
printf("%I64d\n",ans[]);
printf("%I64d\n",ans[]);
printf("%I64d\n",ans[]);
}
return ;
}

HDU 4419 Colourful Rectangle(线段树+扫描线)的更多相关文章

  1. hdu 4419 Colourful Rectangle (离散化扫描线线段树)

    Problem - 4419 题意不难,红绿蓝三种颜色覆盖在平面上,不同颜色的区域相交会产生新的颜色,求每一种颜色的面积大小. 比较明显,这题要从矩形面积并的方向出发.如果做过矩形面积并的题,用线段树 ...

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

    题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...

  3. HDU 1828“Picture”(线段树+扫描线求矩形周长并)

    传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...

  4. hdu 1828 Picture(线段树扫描线矩形周长并)

    线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...

  5. HDU 6096 String 排序 + 线段树 + 扫描线

    String Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others) Problem De ...

  6. HDU 5091---Beam Cannon(线段树+扫描线)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5091 Problem Description Recently, the γ galaxies bro ...

  7. HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  8. HDU 3265 Posters ——(线段树+扫描线)

    第一次做扫描线,然后使我对线段树的理解发生了动摇= =..这个pushup写的有点神奇.代码如下: #include <stdio.h> #include <algorithm> ...

  9. 【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...

随机推荐

  1. SharePoint Word 转换PDF服务介绍及示例

    前言:在SharePoint使用过程中,经常会发现将文档进行格式转换的需求,之前,看到SharePoint 2013有将PPT转换PDF文档的服务,后来,才发现SharePoint 2010开始,就有 ...

  2. ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib

    今天在linux里安装mysql,运行时遇到这样的错误 ERROR 2002 (HY000): Can't connect to local MySQL server through socket ' ...

  3. WPF 打印控件 无弹框打印。

    WPF中打印用到了 PrintDialog类. 其中设置打印属性的是PrintTicket,管理打印机的是PrintQueue. 实例如下: public class PrintDialogHelpe ...

  4. Http协议之Request和Response

    GET / HTTP/1.1表示向服务器用GET方式请求首页,使用HTTP/1.1协议 Cache-Control作用: 用来指定Response-Request遵循的缓存机制.各个指令含义如下Cac ...

  5. PW试验-----verilog

    PWM,脉冲宽度调制.顾名思义,是通过调制脉冲的宽度,即占空比,来实现的.可是使占空比逐渐由最小增加到最大,也可以使占空比由最大减少到最小来实现不同的现象.若用LED灯来显示现象,则可以称作:LED呼 ...

  6. 【Ubuntu日常技巧】【解决】Ubuntu 16 右上角的音量调节通知框不停地闪烁问题

    一. 先上干货 解决问题 1.1 安装工具alsa-tools-gui sudo apt-get install alsa-tools-gui 1.2 通过hdajackretask设置 直接执行命令 ...

  7. Java Hour 9

    有句名言,叫做10000小时成为某一个领域的专家.姑且不辩论这句话是否正确,让我们到达10000小时的时候再回头来看吧. 本文作者Java 现经验约为7 Hour,请各位不吝赐教. Hour 9 方法 ...

  8. C# WPF 之 遍历子控件

    /// <summary> /// 检查非空字段 /// </summary> /// <param name="IsOk"></para ...

  9. php 解决和避免form表单重复提交的方法

    在提交表单的时候,可能遇到网速等导致页面突然加载变慢,用户重复地点击提交按钮,将在数据库产生多条数据,导致不可控情况. 比如下面的情况就会导致表单重复提交: 点击提交按钮两次. 点击刷新按钮. 使用浏 ...

  10. ThinkPHP函数详解:session方法

    ThinkPHP函数详解:session方法 Session方法用于Session 设置.获取.删除和管理操作. Session 用于Session 设置.获取.删除和管理操作 用法    sessi ...