[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)
题目链接 题意不再赘述. 这题和合并石子很类似,但是多了个乘法,而乘法是不满足"大大得大"的,因为两个非常小的负数乘起来也会很大,一个负数乘一个很大的整数会很小,所以我们需要添加一 ...
随机推荐
- SpaceVim - 让你的vim变得更加高效和强大
SpaceVim 中文手册 项 目 主 页: https://spacevim.org Github 地址 : https://github.com/SpaceVim/SpaceVim SpaceVi ...
- MobileNet_v2
研究动机: 神经网络彻底改变了机器智能的许多领域,实现了超人的准确性.然而,提高准确性的驱动力往往需要付出代价:现代先进网络需要高度计算资源,超出许多移动和嵌入式应用的能力. 主要贡献: 发明了一个新 ...
- hadoop基础教程免费分享
提起Hadoop相信大家还是很陌生的,但大数据呢?大数据可是红遍每一个角落,大数据的到来为我们社会带来三方面变革:思维变革.商业变革.管理变革,各行业将大数据纳入企业日常配置已成必然之势.阿里巴巴创办 ...
- php函数var_dump() 、print_r()、echo()
var_dump() 能打印出类型 print_r() 只能打出值 echo() 是正常输出... 需要精确调试的时候用 var_dump(); 一般查看的时候用 print_r() 另外 , ech ...
- Spring mvc中junit测试遇到com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException错误怎么解决
今天遇到图片中的错误,纠结了一下,弄清楚了怎么从控制台中读取错误信息,并修改错误. com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: ...
- linux的slect的脚本适用于交互
[rhuang@localhost ~]$ vi os.sh #!/bin/bash echo "What is your favourite OS?" select var in ...
- C#之Socket通信
0.虽然之前在项目中也有用过Socket,但始终不是自己搭建的,所以对Server,Clinet端以及心跳,断线重连总没有很深入的理解,现在自己搭建了一遍加深一下理解. 服务端使用WPF界面,客户端使 ...
- Jetty入门(1-1)Jetty入门教程
一.Jetty是什么? 1.Jetty 是一个Java语言编写的,开源的Servlet容器和应用服务器. Jetty 极度轻量级.高便携性.功能强大.灵活和扩展性好,而且支持各种技术如SPDY.Web ...
- [CodeForces10D]LCIS(最长公共上升子序列) - DP
Description 给定两个数列,求最长公共上升子序列,并输出其中一种方案. Input&Output Input 第一行一个整数n(0<n<=500),数列a的长度. 第二行 ...
- python手动设置递归调用深度
python超出递归深度时会出现异常: RuntimeError: maximum recursion depth exceeded python默认的递归深度是很有限的,大概是900当递归深度超过这 ...