[IOI1998] Pictures
用线段树维护区间最小值和最小值个数来求一段区间里0的个数,把横的和竖的边分别拿出来,排序,然后每次查一下重复部分的长度即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define MAXN 5000
#define MAXL 10000
#define mid (T[k].l+T[k].r)/2
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-''; ch=getchar();}
return x*f;
} int n,cnt=,ans=;
struct sq{
int x1,y1,x2,y2;
}s[MAXN+];
struct line{
int k,l,r,x;
}l[MAXL+];
struct TREE{
int l,r,x,num,val;
}T[MAXL*]; bool cmp(line x,line y){return x.x<y.x||(x.x==y.x&&x.k<y.k);} void pushdown(int k)
{
int ls=k<<,rs=(k<<)+;
T[ls].x+=T[k].val;T[rs].x+=T[k].val;
T[ls].val+=T[k].val;T[rs].val+=T[k].val;
T[k].val=;
} void combine(int k)
{
int ls=k<<,rs=(k<<)+;
if(T[ls].x==T[rs].x) T[k].x=T[ls].x,T[k].num=T[ls].num+T[rs].num;
else if(T[ls].x<T[rs].x) T[k].x=T[ls].x,T[k].num=T[ls].num;
else T[k].x=T[rs].x,T[k].num=T[rs].num;
} void renew(int k,int l,int r,int ad)
{
if(T[k].l==l&&T[k].r==r)
{T[k].x+=ad;T[k].val+=ad;return;}
if(T[k].val) pushdown(k);
if(r<=mid) renew(k<<,l,r,ad);
else if(l>mid) renew((k<<)+,l,r,ad);
else {renew(k<<,l,mid,ad);renew((k<<)+,mid+,r,ad);}
combine(k);
} int query(int k,int l,int r)
{
// cout<<"q"<<k<<" "<<l<<" "<<r<<endl;
if(T[k].l==l&&T[k].r==r)
{
if(T[k].x>) return T[k].r-T[k].l+;
else return T[k].r-T[k].l+-T[k].num;
}
if(T[k].val) pushdown(k);
if(r<=mid) return query(k<<,l,r);
else if(l>mid) return query((k<<)+,l,r);
else return query((k<<)+,mid+,r)+query(k<<,l,mid);
} void init(int k,int l,int r)
{
//cout<<"init"<<k<<" "<<r<<endl;
T[k].l=l;T[k].r=r;T[k].val=;
if(l==r){T[k].x=;T[k].num=;return;}
init(k<<,l,mid);init((k<<)+,mid+,r);
combine(k);
} int main()
{
n=read();
for(int i=;i<=n;++i)
{
s[i].x1=read()+;s[i].y1=read()+;
s[i].x2=read()+;s[i].y2=read()+;
ans+=(s[i].x2+s[i].y2-s[i].y1-s[i].x1)*;
l[++cnt].k=;l[cnt].x=s[i].x1;l[cnt].l=s[i].y1+;l[cnt].r=s[i].y2;
l[++cnt].k=;l[cnt].x=s[i].x2;l[cnt].l=s[i].y1+;l[cnt].r=s[i].y2;
}
sort(l+,l+cnt+,cmp);init(,,);
// for(int i=1;i<=cnt;i++)
// {
// cout<<l[i].k<<" "<<l[i].x<<" "<<l[i].l<<" "<<l[i].r<<endl;
// }
for(register int i=;i<=cnt;i++)
{
if(!l[i].k){ans-=query(,l[i].l,l[i].r);renew(,l[i].l,l[i].r,);}
else {renew(,l[i].l,l[i].r,-);ans-=query(,l[i].l,l[i].r);} }
cnt=;
for(register int i=;i<=n;++i)
{
l[++cnt].k=;l[cnt].x=s[i].y1;l[cnt].l=s[i].x1+;l[cnt].r=s[i].x2;
l[++cnt].k=;l[cnt].x=s[i].y2;l[cnt].l=s[i].x1+;l[cnt].r=s[i].x2;
}
sort(l+,l+cnt+,cmp);init(,,);
// for(int i=1;i<=cnt;i++)
// {
// cout<<l[i].k<<" "<<l[i].x<<" "<<l[i].l<<" "<<l[i].r<<endl;
// }
for(register int i=;i<=cnt;i++)
{
if(!l[i].k){ans-=query(,l[i].l,l[i].r);renew(,l[i].l,l[i].r,);}
else {renew(,l[i].l,l[i].r,-);ans-=query(,l[i].l,l[i].r);}
}
printf("%d",ans);
return ;
}
[IOI1998] Pictures的更多相关文章
- 【IOI1998】Picture(扫描线+线段树)
问题来源:IOI1998 D2T1 题意:就是在一个平面内给出n个矩形,叫你计算将这些矩形合并以后,新图形的周长. 例如: 上图是原本的矩形们 ---------->合并后的图形 解题思路:拿一 ...
- IOI1998 Polygon [区间dp]
[IOI1998]Polygon 题意翻译 题目可能有些许修改,但大意一致 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符号+(加)或符号*(乘 ...
- 「IOI1998」「LuoguP4342」Polygon(区间dp
P4342 [IOI1998]Polygon - 洛谷 题意翻译 题目可能有些许修改,但大意一致 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符 ...
- [IOI1998]Polygon(区间dp)
[IOI1998]Polygon 题意翻译 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符号+(加)或符号*(乘积)标记. 第一步,删除其中一条 ...
- IOI1998 hdu1828 poj1177 Picture
写了一发扫描线竟然狂WA不止,hdu死活过不了,poj和当时IOI的数据(还花了我1dsdn积分..)都过了. 然后看到谋篇blog里有评论,把数据拿下来发现WA了. 数据是 20 0 1 11 0 ...
- POJ 1179 IOI1998 Polygon
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5472 Accepted: 2334 Description Polyg ...
- luogu P4342 [IOI1998]Polygon
IOI早期这么多dp? 题目要求断掉环上的一边,我们可以断环为链,开两倍数组 容易想到dp,设\(f_{i,j}\)为区间\([i,j]\)的最大值,然后就是个枚举断点的区间dp 不过可能会有负数出现 ...
- 【洛谷P4342】[IOI1998]Polygon
Polygon 比较裸的环形DP(也可以说是区间DP) 将环拆成链,复制到后面,做区间DP即可 #include<iostream> #include<cstdio> usin ...
- 【洛谷 P4342】[IOI1998]Polygon(DP)
题目链接 题意不再赘述. 这题和合并石子很类似,但是多了个乘法,而乘法是不满足"大大得大"的,因为两个非常小的负数乘起来也会很大,一个负数乘一个很大的整数会很小,所以我们需要添加一 ...
随机推荐
- jav音频格式转换 ffmpeg 微信录音amr转mp3
项目背景: 之前公司开发了一个微信公众号,要求把js-sdk录音文件在web网页也能播放.众所周知,html的<audio>标签ogg,mp3,wav,也有所说苹果safari支持m4a格 ...
- Count on a tree
bzoj 2588: Spoj 10628. Count on a tree http://www.lydsy.com/JudgeOnline/problem.php?id=2588 Descrip ...
- 前端面试之angular JS
1. angular的数据绑定采用什么机制?详述原理 angularjs的双向数据绑定,采用脏检查(dirty-checking)机制.ng只有在指定事件触发后,才进入 $digest cycle : ...
- 第一章 创建WEB项目
第一章 创建WEB项目 一.Eclipse创建WEB项目 方法/步骤1 首先,你要先打开Eclipse软件,打开后在工具栏依次点击[File]>>>[New]>>&g ...
- python中 return 的用法
return 语句就是讲结果返回到调用的地方,并把程序的控制权一起返回 程序运行到所遇到的第一个return即返回(退出def块),不会再运行第二个return. 要返回两个数值,写成一行即可: de ...
- 详解Ajax请求(一)前言——同步请求的原理
我们知道,ajax是一种异步请求的方式,想要了解异步请求,就必须要先从同步请求说起.常见的同步请求的方式是form表单的提交,我们先从一种同步请求的示例说起. 我们希望输入姓名可以从后台得到身份证号. ...
- redis数据库各种数据类型的增删改查命令
redis的常用数据操作: redis是key-value的数据结构,每条数据都是一个键值对. 键的类型是字符串并且键不能重复. redis最基本数据类型是string 所以下面的操作可以省略引号&q ...
- 用于水和水蒸汽物性计算的Python模块——iapws
无论是火电还是核电,将能量转化为电能的方式主要还是烧开水,即加热水产生高压蒸汽驱动汽轮机做功再发电.在进行热力循环分析.流动传热计算时,需获得水和水蒸汽的物性参数.网上主流的水蒸汽物性计算程序是上海成 ...
- python网络编程基础(一)
一.C/S架构 客户端/服务端架构 二.OSI七层架构 七层模型,亦称OSI(Open System Interconnection)参考模型,是参考模型是国际标准化组织(ISO)制定的一个用于计算机 ...
- Oracle12c:支持通过创建identity columen来实现创建自增列
oracle12c之前如果需要创建自增列必须要通过sequence+trigger来实现.但是oracle12c已经可以像mysql,sqlserver一样通过identity column来设置自增 ...