题目链接

主要是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. ZooKeeper 安装部署

    一.解压 tar -zxvf zookeeper-3.3.5.tar.gz 二.将zookeeper-3.3.4/conf目录下面的 zoo_sample.cfg修改为zoo.cfg,配置文件内容如下 ...

  2. SPFA算法心得

    SPFA算法是改进后的Bellman-Ford算法,只是速度更快,而且作为一个算法,它更容易理解和编写,甚至比Dijkstra和B-F更易读(当然,Floyd是另一回事了,再也没有比Floyd还好写的 ...

  3. centos安装redis及php-redis扩展

    centos安装redis及php-redis扩展  Linux, WEB 七162012 今天公司同事要求在测试机上安装redis,并且要求让php安装上redis的扩展,redis是一个key-v ...

  4. python chm 中文帮助 (2.7 和 3.4)

    sphinx-build 生成的(htmlhelp) 存在2个问题 1.生成的html 编码 cp2152,需要修改/sphinx/builders/html.py ctx['encoding'] = ...

  5. Java for LeetCode 054 Spiral Matrix

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...

  6. poj 1007 DNA Sorting 解题报告

    题目链接:http://poj.org/problem?id=1007 本题属于字符串排序问题.思路很简单,把每行的字符串和该行字符串统计出的字母逆序的总和看成一个结构体.最后把全部行按照这个总和从小 ...

  7. Eclipse设置C++自动补全变量名快捷键Alt + /

    使用快捷键:Alt+/ 要是还是有些场合不能提示,按照下列步骤 Window-Preferences-c/c++-Editor-Content Assist-Advanced 将未勾选的全部勾选

  8. 在Win8中创建热点,共享网络

    在Win8中创建热点,共享网络 办公室中,我独享10M光纤,没什么要下的,便想利用来更新下Ipad里面的程序,下点公开课.那在不利用软件[用很多wifi共享的软件],从win7开始 系统本身就自带相关 ...

  9. 组合数(codevs 1631)

    1631 组合数  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description 组合数C(N, K)表示 ...

  10. 发现磁盘的shell

    #!/bin/bash #set -x diskarray=(`cat /proc/diskstats |grep -E "\bsd[a-z]\b|\bxvd[a-z]\b|\bvd[a-z ...