传送门

看到 $n<=5000$,直接暴力枚举左右两条竖线

然后考虑怎么计算高度在某个范围内,左端点小于等于某个值,右端点大于等于某个值的横线数量

直接用权值树状数组维护当前高度在某个区间内的横线数量

考虑先固定左边的竖线,然后枚举从左到右枚举右边的竖线,那么随着右边竖线的右移,合法的横线(右端点大于等于某个值的横线)数量只会越来越少

所以枚举右边竖线的时候同时动态维护一个指向当前最左的右端点合法的横线,然后动态维护树状数组就行了

答案也很容易计算,在固定了左右竖线的情况下,设中间有 $p$ 个最小的不可分割的矩形,那么贡献即为 $p(p+1)/2$

(枚举大矩形包含了 $k$ 小矩形,那么就是 $\sum_{k=1}^{p}(p-k+1)$)

然后因为坐标系有负数所以统一加上 $5001$ 即可

复杂度 $n^2 \log 10000$,很稳

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=;
struct Line {//竖线
int x,l,r;
Line (int _x=,int _l=,int _r=) { x=_x,l=_l,r=_r; }
inline bool operator < (const Line &tmp) const {
return x!=tmp.x ? x<tmp.x : l<tmp.l;
}
}D[N];
struct Line2 {//横线
int h,l,r;
Line2 (int _h=,int _l=,int _r=) { h=_h,l=_l,r=_r; }
}H1[N],H2[N];
inline bool cmp1(Line2 &A,Line2 &B) { return A.l!=B.l ? A.l<B.l : A.r<B.r; }//把横线按左端点排序
inline bool cmp2(Line2 &A,Line2 &B) { return A.r!=B.r ? A.r<B.r : A.l<B.l; }//按右端点排序
int n,m,md,mh;
struct BIT {//树状数组
int t[N];
inline void init() { memset(t,,sizeof(t)); }
inline void add(int x,int v) { while(x<=m) t[x]+=v,x+=x&-x; }
inline int ask(int x) { int res=; while(x) res+=t[x],x-=x&-x; return res; }
}T;
ll Ans;
int main()
{
n=read(); int a,b,c,d;
for(int i=;i<=n;i++)
{
a=read()+,b=read()+,c=read()+,d=read()+;
m=max(m,max(b,d));
if(a==c)
{
if(b>d) swap(b,d);
D[++md]=Line(a,b,d);
}
else
{
if(a>c) swap(a,c);
H1[++mh]=Line2(b,a,c); H2[mh]=H1[mh];
}
}
sort(D+,D+md+); sort(H1+,H1+mh+,cmp1); sort(H2+,H2+mh+,cmp2);
for(int i=;i<=md;i++)//枚举左边的竖线
{
int l=,r=;//动态维护指针
while(l<=mh&&H1[l].l<=D[i].x) T.add(H1[l].h,),l++;
while(r<=mh&&H2[r].r<D[i].x) T.add(H2[r].h,-),r++;
for(int j=i+;j<=md;j++)
{
while(r<=mh&&H2[r].r<D[j].x)
{
if(H2[r].l<=D[i].x) T.add(H2[r].h,-);//注意要判断是之前加入过的横线
r++;
}
if(D[i].x==D[j].x) continue;//相等不合法
int L=max(D[i].l,D[j].l),R=min(D[i].r,D[j].r);
if(L>=R) continue;//相等不合法
int p=T.ask(R)-T.ask(L-)-; if(p<=) continue;//构不成矩形
Ans+=1ll*p*(p+)/;//累计贡献
}
while(r<=mh)//记得清空树状数组
{
if(H2[r].l<=D[i].x) T.add(H2[r].h,-);
r++;
}
}
printf("%lld\n",Ans);
return ;
}

Codeforces 1194E. Count The Rectangles的更多相关文章

  1. Codeforces - 1194E - Count The Rectangles - 扫描线

    https://codeforc.es/contest/1194/problem/E 给5000条正常的(同方向不会重叠,也不会退化成点的)线段,他们都是平行坐标轴方向的,求能组成多少个矩形. 先进行 ...

  2. Codeforces 1197E Count The Rectangles(树状数组+扫描线)

    题意: 给你n条平行于坐标轴的线,问你能组成多少个矩形,坐标绝对值均小于5000 保证线之间不会重合或者退化 思路: 从下到上扫描每一条纵坐标为y的水平的线,然后扫描所有竖直的线并标记与它相交的线,保 ...

  3. Educational Codeforces Round 68 E. Count The Rectangles

    Educational Codeforces Round 68 E. Count The Rectangles 传送门 题意: 给出不超过\(n,n\leq 5000\)条直线,问共形成多少个矩形. ...

  4. Codeforces 372 B. Counting Rectangles is Fun

    $ >Codeforces \space 372 B.  Counting Rectangles is Fun<$ 题目大意 : 给出一个 \(n \times m\) 的 \(01\) ...

  5. codeforces 713B B. Searching Rectangles(二分)

    题目链接: B. Searching Rectangles time limit per test 1 second memory limit per test 256 megabytes input ...

  6. codeforces D. Count Good Substrings

    http://codeforces.com/contest/451/problem/D 题意:给你一个字符串,然后找出奇数和偶数长度的子串的个数,这些字串符合,通过一些连续相同的字符合并后是回文串. ...

  7. CodeForces - 1189E Count Pairs(平方差)

    Count Pairs You are given a prime number pp, nn integers a1,a2,…,ana1,a2,…,an, and an integer kk. Fi ...

  8. Codeforces 1188B - Count Pairs(思维题)

    Codeforces 题面传送门 & 洛谷题面传送门 虽说是一个 D1B,但还是想了我足足 20min,所以还是写篇题解罢( 首先注意到这个式子里涉及两个参数,如果我们选择固定一个并动态维护另 ...

  9. codeforces 451D Count Good Substrings

    题意:给定一个字符串,求有多少个奇数子串和多少偶数子串为 “回文串”   这边回文串很特殊之含有  ab  两种字母  而且  相邻的字母相同则消去一个  一直到不存在相邻的相同. 思路:  在这种串 ...

随机推荐

  1. zabbix监控远端主机

    接着上一篇博客,zabbix监控搭建起来以后,怎么用来监控其他主机呢,这一篇就来简单讲一下,希望对大家有所帮助. 安装一些依赖包 [root@winter ~]# yum install curl c ...

  2. flask读书记录

    1. 在flask中,如果我们在视图函数中使用data = request.get_json()方法获取数据,那么在客户端发送POST请求时,就需要设置设置正确的Content-Type首部.在aja ...

  3. laravel 文件上传总结

    调用 store 方法会生成唯一的 ID 来作为文件名,如果想获取原件本来的名称可以使用 $file = $request->file('file'); $file->getClientO ...

  4. MySQL5.7快速修改表中字段长度

    在mysql 5.5版本时,商用环境升级,有一个表存在六千多万数据,升级时需要修改这个表其中一个varchar类型字段的长度,当时用了大概4个多小时,还没有结束,之后我们系统mysql升级到5.7版本 ...

  5. android canvas drawtext 字高

    Paint pFont = new Paint(); Rect rect = new Rect(); pFont.getTextBounds("豆", 0, 1, rect); L ...

  6. STL -- heap结构及算法

    STL -- heap结构及算法 heap(隐式表述,implicit representation) 1. heap概述 : vector + heap算法 heap并不归属于STL容器组件,它是个 ...

  7. Nginx服务应用

    虚拟主机 基于域名的虚拟主机 所谓基于域名的虚拟主机,意思就是通过不同的域名区分不同的虚拟主机,基于域名的虚拟主机是企业应用最广的虚拟主机类型,几乎所有对外提供服务的网站都是使用基于域名的虚拟主机 基 ...

  8. Oracle 字段监控 ( column monitor)

    Oracle 字段监控 ( column monitor) */--> Oracle 字段监控 ( column monitor) Table of Contents 1. 开启与关闭 2. 字 ...

  9. 4、kubernetes应用入门

    本随笔接前两两章,建立离master主节点和node01.node02.node03三个节点 kubectl子命令 master ~]# kubectl kubectl controls the Ku ...

  10. Java 语言实现 MD5 加密

    Java 语言实现 MD5 加密 背景说明 在实际项目中,为了安全性考虑,经常要求账号密码是以加密后的密文形式,保存到数据库中. 这样,即使有人获取到了数据库中的密文密码,也不知道明文密码信息是什么, ...