并不对劲的CF1194E:Count The Rectangles
题意
有\(n\)(\(n\leq 5000\))个平行于x轴或平行于y轴的线段。求这些线段围成了多少个长方形。由多个长方形拼成的也算。
题解
考虑暴力的做法:先分别计算每条横着的线与哪些竖着的线有交点,再枚举两条横着的线,求与它们都有交点的线的个数,在这些线中选两条和这两条横着的线拼成长方形。
发现与同一条竖着的线有交点的横线一定是把所有横线按纵坐标排序后连续的一段。
感谢伟大的YSF!!!

代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define view(u,k) for(int k=fir[u];~k;k=nxt[k])
#define LL long long
#define maxn 5007
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(LL x)
{
if(x==0){putchar('0'),putchar('\n');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar('\n');
return;
}
struct node{int x,l,r;}a[maxn],b[maxn];
int n,tr[maxn+maxn],maxk=5001,sz=10002,cnta,cntb;
LL ans;
vector<int>ed[maxn];
node maken(int x,int l,int r){node tmp;tmp.x=x,tmp.l=l,tmp.r=r;return tmp;}
LL c(int x){return (LL)x*(x-1ll)/2ll;}
int lt(int x){return x&(-x);}
void add(int x,int k){for(;x<=sz;x+=lt(x))tr[x]+=k;return;}
int ask(int x){int k=0;for(;x;x-=lt(x))k+=tr[x];return k;}
int yes(node x,node y)
{
if(y.l<=x.x&&x.x<=y.r&&x.l<=y.x&&y.x<=x.r)return 1;
return 0;
}
bool cmpx(node x,node y){return x.x<y.x;}
bool cmpr(int x,int y){return b[x].r<b[y].r;}
int main()
{
n=read();
rep(i,1,n)
{
int x1=read(),y1=read(),x2=read(),y2=read();
if(x1>x2)swap(x1,x2);
if(y1>y2)swap(y1,y2);
if(y1==y2)a[++cnta]=maken(y1,x1,x2);
else b[++cntb]=maken(x1,y1,y2);
}
sort(a+1,a+cnta+1,cmpx);
rep(i,1,cnta)
{
rep(j,1,cntb)if(yes(a[i],b[j]))
{
add(b[j].x+maxk,1);
ed[i].push_back(j);
}
int li=ed[i].size(),now=-1;
sort(ed[i].begin(),ed[i].end(),cmpr);
rep(j,i+1,cnta)
{
while((now+1)<li&&b[ed[i][now+1]].r<a[j].x)add(b[ed[i][now+1]].x+maxk,-1),now++;
int num=ask(a[j].r+maxk)-ask(a[j].l+maxk-1);
ans+=c(num);
}
while((now+1)<li)add(b[ed[i][now+1]].x+maxk,-1),now++;
}
write(ans);
return 0;
}
并不对劲的CF1194E:Count The Rectangles的更多相关文章
- Educational Codeforces Round 68 E. Count The Rectangles
Educational Codeforces Round 68 E. Count The Rectangles 传送门 题意: 给出不超过\(n,n\leq 5000\)条直线,问共形成多少个矩形. ...
- 【EDU68 E】 Count The Rectangles 数据结构算几何
CF # 题意 总共有5000条线段,这些线段要么水平,要么垂直,问这些线段组成了多少矩形. # 思路 这是一个n*n*(log)的思路 自己一开始想着枚举两条垂直边,想着怎么把水平的边插入,再进行冗 ...
- Codeforces 1194E. Count The Rectangles
传送门 看到 $n<=5000$,直接暴力枚举左右两条竖线 然后考虑怎么计算高度在某个范围内,左端点小于等于某个值,右端点大于等于某个值的横线数量 直接用权值树状数组维护当前高度在某个区间内的横 ...
- Codeforces - 1194E - Count The Rectangles - 扫描线
https://codeforc.es/contest/1194/problem/E 给5000条正常的(同方向不会重叠,也不会退化成点的)线段,他们都是平行坐标轴方向的,求能组成多少个矩形. 先进行 ...
- Codeforces 1197E Count The Rectangles(树状数组+扫描线)
题意: 给你n条平行于坐标轴的线,问你能组成多少个矩形,坐标绝对值均小于5000 保证线之间不会重合或者退化 思路: 从下到上扫描每一条纵坐标为y的水平的线,然后扫描所有竖直的线并标记与它相交的线,保 ...
- 面向对象设计模式_享元模式(Flyweight Pattern)解读
场景:程序需要不断创建大量相似的细粒度对象,会造成严重的内存负载.我们可以选择享元模式解决该问题. 享元抽象:Flyweight 描述享元的抽象结构.它包含内蕴和外蕴部分(别被术语迷惑,这是一种比较深 ...
- Educational Codeforces Round 68
目录 Contest Info Solutions A.Remove a Progression B.Yet Another Crosses Problem C.From S To T D.1-2-K ...
- nodejs api 中文文档
文档首页 英文版文档 本作品采用知识共享署名-非商业性使用 3.0 未本地化版本许可协议进行许可. Node.js v0.10.18 手册 & 文档 索引 | 在单一页面中浏览 | JSON格 ...
- [ACM_暴力][ACM_几何] ZOJ 1426 Counting Rectangles (水平竖直线段组成的矩形个数,暴力)
Description We are given a figure consisting of only horizontal and vertical line segments. Our goal ...
随机推荐
- Leetcode题目283.移动零(简单)
题目描述: 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 必须在原 ...
- 启动maven项目时报错Failed to start component [StandardEngine[Tomcat]]: A child container failed during start
详细错误信息:Failed to execute goal org.apache.tomcat.maven:tomcat7-maven-plugin:2.2:run (default-cli) on ...
- java课后实验性问题2
课后作业一:计算组合数 程序设计思想: 从键盘获取组合数,判断是否构成组合数.分别用三种方法计算组合数输出. 程序流程图: import java.util.Scanner; public class ...
- VS Code文本编辑快捷操作(2)
1. 光标移动 移动光标最常用的就是方向键,但是方向键每次只能把光标移动一个位置,可以说是一种相对低效的方式.下面介绍针对单词.行.代码块.整个文档等多种光标移动方式. 1.1 ...
- java客户端验证https连接(忽略证书验证和证书验证两种方式)
首先根据如下操作生成证书,配置springboot https,生成一个简单的https web服务 https://www.cnblogs.com/qq931399960/p/11889349.ht ...
- [转]Html 页面常用单词
Html 页面常用单词 本文来自:https://gitee.com/opencc/SchoolAppDemo 第2批: JavaScript ready 准备 function 函数 disappe ...
- x86架构64位模式下的寄存器列表
在此列出x86架构处理器在64位模式下的可用寄存器列表,方便查阅- 这里要注意的是,在64位模式下,所有通用寄存器都能访问第8位部分,低16位部分以及低32位部分. 以下是64位模式下AMD64 AB ...
- Qt编写自定义控件32-等待进度条控件
一.前言 在各种各样的执行任务界面,有时候需要比较多的时间,需要给出一个直观的等待进度条表示当前正在执行的进度,而不至于懵逼在那里,用户不会觉得程序死了还是干嘛了. 等待进度条有好几种办法,比如直接叫 ...
- 深入理解Attention机制
要了解深度学习中的注意力模型,就不得不先谈Encoder-Decoder框架,因为目前大多数注意力模型附着在Encoder-Decoder框架下,当然,其实注意力模型可以看作一种通用的思想,本身并不依 ...
- Flutter路由_fluro引入配置和使用
Flutter本身提供了路由机制,作个人的小型项目,完全足够了.但是如果你要作企业级开发,可能就会把入口文件变得臃肿不堪.而再Flutter问世之初,就已经了企业级路由方案fluro. flutter ...