P1856 [USACO5.5]矩形周长Picture
$len$ $sum$ $num$ $flag\_l$ $flage\_r$分别表示该区间
覆盖长度--整体覆盖次数--覆盖段数--左右端点是否覆盖
将上下边按高度排序不断扫下来
$num$是用来处理高度的
inline void Update(LL now,LL l,LL r){
if(tree[now].sum){
tree[now].num=1,
tree[now].len=r-l+1,
tree[now].flag_l=tree[now].flag_r=1;
}else if(l==r){
tree[now].len=tree[now].num=tree[now].flag_l=tree[now].flag_r=0;
}else{
LL son0=now<<1,son1=son0|1;
tree[now].len=tree[son0].len+tree[son1].len,
tree[now].num=tree[son0].num+tree[son1].num;
if(tree[son0].flag_r&&tree[son1].flag_l)
--tree[now].num;
tree[now].flag_l=tree[son0].flag_l,
tree[now].flag_r=tree[son1].flag_r;
}
}
现在来理解一下更新
如果该区间至少覆盖了一次,显然只覆盖段数为$1$,注意线段树里长度是以段分的
如果没被覆盖
$(1)$叶子节点,全部清空
$(2)$长度$=$左右子树长度 覆盖段数也差不多,再加一下合并
My complete code:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<string>
using namespace std;
typedef long long LL;
const LL maxn=1e5;
inline LL Read(){
LL x=0,f=1; char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1; c=getchar();
}
while(c>='0'&&c<='9'){
x=(x<<3)+(x<<1)+c-'0'; c=getchar();
}return x*f;
}
struct node{
LL l,r,h,val;
}a[maxn];
struct code{
LL len,sum,num,flag_l,flag_r;
}tree[maxn];
LL n,mi,mx,ans,num,last;
inline bool cmp(node x,node y){
return x.h<y.h||(x.h==y.h&&x.val>y.val);
}
inline void Update(LL now,LL l,LL r){
if(tree[now].sum){
tree[now].num=1,
tree[now].len=r-l+1,
tree[now].flag_l=tree[now].flag_r=1;
}else if(l==r){
tree[now].len=tree[now].num=tree[now].flag_l=tree[now].flag_r=0;
}else{
LL son0=now<<1,son1=son0|1;
tree[now].len=tree[son0].len+tree[son1].len,
tree[now].num=tree[son0].num+tree[son1].num;
if(tree[son0].flag_r&&tree[son1].flag_l)
--tree[now].num;
tree[now].flag_l=tree[son0].flag_l,
tree[now].flag_r=tree[son1].flag_r;
}
}
LL ci;
void Add(LL now,LL l,LL r,LL lt,LL rt,LL v){
if(lt<=l&&rt>=r){
tree[now].sum+=v,
Update(now,l,r);
return;
}
LL mid=(l+r)>>1,son0=now<<1,son1=son0|1;
if(lt<=mid)
Add(son0,l,mid,lt,rt,v);
if(rt>mid)
Add(son1,mid+1,r,lt,rt,v);
Update(now,l,r);
}
int main(){
n=Read();
for(LL i=1;i<=n;++i){
LL x1=Read(),y1=Read(),x2=Read(),y2=Read();
mx=max(mx,max(x1,x2)),
mi=min(mi,min(x1,x2)),
a[++num]=(node){x1,x2,y1,1},
a[++num]=(node){x1,x2,y2,-1};
}
if(mi<=0){
for(LL i=1;i<=num;++i)
a[i].l+=-mi+1,
a[i].r+=-mi+1;
mx+=-mi;
}
sort(a+1,a+1+num,cmp);
for(LL i=1;i<=num;++i){
Add(1,1,mx,a[i].l,a[i].r-1,a[i].val);
while(a[i].h==a[i+1].h&&a[i].val==a[i+1].val){
++i,
Add(1,1,mx,a[i].l,a[i].r-1,a[i].val);
}
ans+=abs(last-tree[1].len),
last=tree[1].len,
ans+=2*tree[1].num*(a[i+1].h-a[i].h);
}
printf("%lld",ans);
return 0;
}
P1856 [USACO5.5]矩形周长Picture的更多相关文章
- P1856 [USACO5.5]矩形周长Picture[扫描线]
题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...
- 洛谷P1856 [USACO5.5]矩形周长Picture
题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...
- luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树
Code: #include<bits/stdc++.h> #define maxn 200007 #define inf 100005 using namespace std; void ...
- [题解]P1856 [USACO5.5]矩形周长Picture
Loli 考试的题目之一 题目地址 \(N^2\)做法 #include <cstdio> #include <cstring> #define re register #de ...
- Luogu P1856 [USACO5.5]矩形周长Picture
线段树+扫描线 经典的扫描线问题 首先将一个矩形看作由竖着的两条边和横着的两条边构成 那分成两次考虑,一次考虑竖边,一次考虑横边 首先考虑横边 如图两个矩形,现将横边擦去,留下竖边,将平面划分成3个区 ...
- [USACO5.5] 矩形周长Picture
https://www.luogu.org/problemnew/show/P1856 1.每个矩形由两条横向边和两条纵向边组成. 2.对于横向边,按纵坐标排序.设当前讨论的边为 A [s , t] ...
- luogu1856 [USACO5.5]矩形周长Picture
看到一坨矩形就要想到扫描线.(poj atantis) 我们把横边竖边分开计算,因为横边竖边其实没有区别,以下论述全为考虑竖边的. 怎样统计一个竖边对答案的贡献呢?答:把这个竖边加入线段树,当前的总覆 ...
- Luogu1856 [USACO5.5]矩形周长Picture (线段树扫描线)
对于横轴,加上与上一次扫描的差值:对于竖轴,加上高度差与区间内不相交线段\(*2\)的积: 难点在pushdown,注意维护覆盖关系.再就注意负数 #include <iostream> ...
- 「USACO5.5」矩形周长Picture
题目描述 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 编写一个程序计算周长. 如图1所示7个矩形. 如图2所 ...
随机推荐
- cocos2d-x 学习记录
不积跬步,无以至千里.不积小流,无以成江海. 開始学习cocos2d-x ,路漫漫其修远兮.加油!
- [CentOS]怎样解决gcc版本号冲突?
今天碰到一个比較坑爹的问题.在centos上用yum安装编译环境,执行: yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel o ...
- dubbo应用程序的单元测试环境搭建(springtest,powermock,mockito)
转:http://blog.csdn.net/yys79/article/details/66472797 最近,项目中频繁用到dubbo,而且java工程用引用了几十个关联系统的服务(如用户认证,基 ...
- PHP中读取文件的几个方法
整理了一下PHP中读取文件的几个方法,方便以后查阅. 1.fread string fread ( int $handle , int $length ) fread() 从 handle 指向的文件 ...
- Android开发有用的三方网站
聚合数据-免费数据调用 https://www.juhe.cn/ 有赞- 免费的微商城 http://youzan.com/ 秀米微信图文编辑器 http://xiumi.us/ 禅道项目管理软件 h ...
- 微软Azure公有云个人用户是否能支付得起?
个人建立自己的站点是普通"白领"的愿望.由于,我们的大脑分泌的脑汁须要排泄渠道.怎么办呢? 依据微软公有云的公开报价(Pricing),租用单核CPU.0.75GB内存,20GB硬 ...
- java代码实现输出指定以.java结尾的文件的绝对路径
package 输出指定文件绝对路径; import java.io.File; /* * 需求:请大家把"E:\\JAVA语言"文件夹下全部的java结尾的文件的绝对路径给输出在 ...
- 26:IPMaskCheck识别有效的ip地址和掩码并分类统计
题目描述 请解析IP地址和对应的掩码,进行分类识别.要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类. 所有的IP地址划分为 A,B,C,D,E五类 A类地址1.0.0.0~126.2 ...
- hdu 1203 I NEED A OFFER!(01背包)
题意:"至少一份offer的最大概率".即求拿不到offer的最小概率 (得到offer的最大概率 = 1 - 反例的最小概率). 状态转移方程:dp[j]= Min(dp[j], ...
- VTK学习之路——画画我的小苹果
数据集主要由描写叙述数据集几何形状的点集数据及构成数据集的单元构成,因此构建数据集的主要任务就是确定点集和构建单元,本演示样例程序构建了一个苹果的实体,然后绘制苹果.演示样例程序运行的过程例如以下: ...