https://www.luogu.org/problemnew/show/P1856

1.每个矩形由两条横向边和两条纵向边组成.

2.对于横向边,按纵坐标排序。设当前讨论的边为 A [s , t]

如果 A 是某个矩形的靠下的边,在树中查询[s,t]区间中被覆盖的长度为x,那么加上这条边后将增加(t-s-x);

如果 A 是某个矩形的靠上的边,先删除它的对应边,再在树中查询[s,t]区间中被覆盖的长度为x,那么加上这条边后将增加(t-s-x);

3、对于纵向边,按横坐标排序,讨论方法与横向边相同。

注意建树方式是以单位线段为叶子节点

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath> #define LL long long using namespace std;
const int MAXN = 2e4 + ;
const int INF = 1e9; int n,m,Ans = ; #define Max 10001 inline void read(int &x){
x=; int f=; register char c = getchar();
while(c>''||c<''){ if(c=='-')f=-; c=getchar(); }
while(c>=''&&c<=''){ x=x*+c-''; c=getchar(); } x*=f;
} struct Seg_Ment{
int s,t,id,p; // s、t线段端点 p是排序依据 id--排序之前的编号
Seg_Ment(int a,int b,int c,int d):s(a),t(b),p(c),id(d){}
Seg_Ment(){ s=t=p=id=; }
bool operator < (const Seg_Ment a) const {
return p < a.p;
}
}x[MAXN],y[MAXN]; int lazy[MAXN << ],cnt[MAXN << ],l,r; inline void Push_Down(int u){
int ls = u << ,rs = u << |;
lazy[ls] += lazy[u],cnt[ls] += lazy[u],cnt[rs] += lazy[u],lazy[rs] += lazy[u];
lazy[u] = ;
} void UpDate(int u,int L,int R,int Del){
if(lazy[u]) Push_Down(u);
if(l <= L && R <= r){
cnt[u] += Del,lazy[u] += Del;
}
else if(L + < R){
int Mid = (L+R) >>,ls = u<<,rs = u<<|;
if(l <= Mid && L <= r) UpDate(ls,L,Mid,Del);
if(r >= Mid && l <= R) UpDate(rs,Mid,R,Del);
}
} int query(int u,int L,int R){
if(lazy[u]) Push_Down(u);
if(l <= L && R <= r && cnt[u] > ) return R - L;
if(L + < R){
int Mid = L+R >>,a = ,b = ;
if(l <= Mid) a = query(u<<,L,Mid);
if(r >= Mid) b = query(u<<|,Mid,R);
return a + b;
}
return ;
} int main(int argc,char *argv[]){
freopen("gg.out", "w", stdout);
cin >> n;
for(int i = ; i <= n; i ++) {
cout << i << ":" << " " << tan(i) << endl;
}
return ;
int x1,y1,xx,yy;
read(n);
for(int i=; i<=n; ++i){
read(x1),read(y1),read(xx),read(yy);
x1 += Max,xx += Max,y1 += Max, yy += Max;
x[i] = Seg_Ment(x1,xx,y1,i),y[i] = Seg_Ment(y1,yy,x1,i);
x[i + n] = Seg_Ment(x1,xx,yy,i + n),y[i + n] = Seg_Ment(y1,yy,xx,i + n);
} return ;
sort(x + ,x + * n + );
sort(y + ,y + * n + );
memset(lazy,,sizeof lazy ); memset(cnt,,sizeof cnt );
for(int i=; i<=n * ; ++i){
l = x[i].s, r = x[i].t;
if(x[i].id <= n){
Ans += abs(r - l - query(,,MAXN));
UpDate(,,MAXN,);
}
else {
UpDate(,,MAXN,-);
Ans += abs(r - l - query(,,MAXN));
}
}
memset(lazy,,sizeof lazy ); memset(cnt,,sizeof cnt );
for(int i=; i<=n * ; ++i){
l = y[i].s,r = y[i].t;
if(y[i].id <= n){
Ans += abs(r - l - query(,,MAXN));
UpDate(,,MAXN,);
}
else{
UpDate(,,MAXN,-);
Ans += abs(r - l - query(,,MAXN));
}
}
cout << Ans << endl;
return ;
}

[USACO5.5] 矩形周长Picture的更多相关文章

  1. P1856 [USACO5.5]矩形周长Picture

    P1856 [USACO5.5]矩形周长Picture $len$            $sum$              $num$             $flag\_l$ $flage\_ ...

  2. P1856 [USACO5.5]矩形周长Picture[扫描线]

    题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...

  3. 洛谷P1856 [USACO5.5]矩形周长Picture

    题目背景 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 题目描述 编写一个程序计算周长. 如图1所示7个矩形. ...

  4. luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树

    Code: #include<bits/stdc++.h> #define maxn 200007 #define inf 100005 using namespace std; void ...

  5. luogu1856 [USACO5.5]矩形周长Picture

    看到一坨矩形就要想到扫描线.(poj atantis) 我们把横边竖边分开计算,因为横边竖边其实没有区别,以下论述全为考虑竖边的. 怎样统计一个竖边对答案的贡献呢?答:把这个竖边加入线段树,当前的总覆 ...

  6. Luogu P1856 [USACO5.5]矩形周长Picture

    线段树+扫描线 经典的扫描线问题 首先将一个矩形看作由竖着的两条边和横着的两条边构成 那分成两次考虑,一次考虑竖边,一次考虑横边 首先考虑横边 如图两个矩形,现将横边擦去,留下竖边,将平面划分成3个区 ...

  7. [题解]P1856 [USACO5.5]矩形周长Picture

    Loli 考试的题目之一 题目地址 \(N^2\)做法 #include <cstdio> #include <cstring> #define re register #de ...

  8. Luogu1856 [USACO5.5]矩形周长Picture (线段树扫描线)

    对于横轴,加上与上一次扫描的差值:对于竖轴,加上高度差与区间内不相交线段\(*2\)的积: 难点在pushdown,注意维护覆盖关系.再就注意负数 #include <iostream> ...

  9. 「USACO5.5」矩形周长Picture

    题目描述 墙上贴着许多形状相同的海报.照片.它们的边都是水平和垂直的.每个矩形图片可能部分或全部的覆盖了其他图片.所有矩形合并后的边长称为周长. 编写一个程序计算周长. 如图1所示7个矩形. 如图2所 ...

随机推荐

  1. 使用RabbitMQ实现分布式事务

    RabbitMQ解决分布式事务思路: 案例: 经典案例,以目前流行点外卖的案例,用户下单后,调用订单服务,让后订单服务调用派单系统通知送外卖人员送单,这时候订单系统与派单系统采用MQ异步通讯. Rab ...

  2. javascript 垃圾回收机制和内存管理

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 垃圾回收机制的原理是找到不再被使用的变量,然后释放其占用的内存,但这个过程不是时时的,因为其开销比较大,所 ...

  3. C#基础--Ref与Out区别

    两者都是按地址传递的,使用后都将改变原来参数的数值. class Program { static void Main(string[] args) { int num = 1; Method(ref ...

  4. js之split拆分字符串

    js之split拆分字符串 1.单字符拆分 let arr = str.split(',') 2.多字符拆分 let arr = str.split(/[(),]/)

  5. Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (16944839 > 16777216). You can change this value on the server by setting the max_allowed_packet' variable.

    今天发现task微服务的error日志报如下错误: Cause: com.mysql.jdbc.PacketTooBigException: Packet for query is too large ...

  6. ES6箭头函数及this指向

    箭头函数(=>):函数简写 无参数:() => {} 单个参数:x => {} 多个参数:(x, y) => {} 解构参数:({x, y}) => {} 嵌套使用:部署 ...

  7. 基2时抽8点FFT的matlab实现流程及FFT的内部机理

    前言 本来想用verilog描述FFT算法,虽然是8点的FFT算法,但写出来的资源用量及时延也不比调用FFT IP的好, 还是老实调IP吧,了解内部机理即可,无需重复发明轮子. 参考 https:// ...

  8. Axure流程图

    什么是流程图 一个流程图可用于展示各种各样的处理流程,包括用例流程.商业流程.页面流程等.在Axure中,流程图常用于提供一个高保真的.能通过所设计的页面来完成的任务视图.一张简明的流程图,能促进和其 ...

  9. 【Day5】1.Request对象之Header伪装策略

    import urllib.request as ur import user_agent request = ur.Request( url='https://edu.csdn.net/', hea ...

  10. c# 运算符和表达式