【EDU68 E】 Count The Rectangles 数据结构算几何
# 题意
总共有5000条线段,这些线段要么水平,要么垂直,问这些线段组成了多少矩形。
# 思路
这是一个n*n*(log)的思路

自己一开始想着枚举两条垂直边,想着怎么把水平的边插入,再进行冗斥等数出与两边都相交的数量。但是做不出来。
后来学习了如图的思路。
我们枚举垂直边,对于i 来说,因为三条红线与i 有交点,我们就标记三条红线。然后枚举剩下垂直边j ,k。如果这些垂直边与红线相交,就把对答案的贡献算进去。
具体实现可以用树状数组优化:算垂直边与红线交点个数。
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a)
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
template<class T> void _R(T &x) { cin >> x; }
void _R(int &x) { scanf("%d", &x); }
void _R(ll &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { scanf(" %c", &x); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template<class T, class... U> void R(T &head, U &... tail) { _R(head); R(tail...); }
template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
}
const int inf = 0x3f3f3f3f;
const int mod = 1e9+;
/**********showtime************/
const int maxm = ;
const int maxn = ;
struct Q{
int le,ri;
int up,down;
} qujian[maxm];
struct VER{ //垂直
int x;
int y1,y2;
}ver[maxn];
struct HOR{ //水平
int y;
int x1,x2;
}hor[maxn];
bool cmpv(VER a, VER b){
return a.x < b.x;
}
bool cmph(HOR a, HOR b){
return a.x2 < b.x2;
}
const int N = * maxn;
ll sum[N];
int lowbit(int x) {
return x & (-x);
}
void update(int x, int val) {
while(x <= N){
sum[x] += val;
x += lowbit(x);
}
}
ll getsum(int x) {
ll res = ;
while(x > ) {
res += sum[x];
x -= lowbit(x);
}
return res;
}
ll C(ll v) {
return (v * (v-)/ );
}
int main(){
int n; scanf("%d", &n);
int totv = , toth = ;
for(int i=; i<=n; i++) {
int x1,x2,y1,y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x1 += ; y1 += ; x2 += ; y2 += ;
if(x1 == x2) {
ver[++totv].x = x1;
ver[totv].y1 = min(y1, y2);
ver[totv].y2 = max(y1, y2);
}
else {
hor[++toth].y = y1;
hor[toth].x1 = min(x1, x2);
hor[toth].x2 = max(x1, x2);
}
}
sort(ver+, ver++totv, cmpv);
sort(hor+, hor++toth, cmph);
ll ans = ;
for(int i=; i<=totv; i++) {
queue<int>que;
memset(sum, , sizeof(sum));
for(int j=; j<=toth; j++) {
if(hor[j].y <= ver[i].y2 && hor[j].y >= ver[i].y1) {
if(hor[j].x1 <= ver[i].x) {
que.push(j);
update(hor[j].y, );
}
}
}
for(int j=i+; j<=totv; j++) {
while(!que.empty() && hor[que.front()].x2 < ver[j].x) {
update(hor[que.front()].y, -);
que.pop();
}
ans += C(getsum(ver[j].y2) - getsum(ver[j].y1-));
}
}
printf("%lld\n", ans);
return ;
}
(感想:自己对n^2枚举的理解过于简单。这道题中第一层n遍历中 其实套了两个n的遍历。值得学习)
【EDU68 E】 Count The Rectangles 数据结构算几何的更多相关文章
- HDU 5128.The E-pang Palace-计算几何
The E-pang Palace Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Othe ...
- Educational Codeforces Round 68 E. Count The Rectangles
Educational Codeforces Round 68 E. Count The Rectangles 传送门 题意: 给出不超过\(n,n\leq 5000\)条直线,问共形成多少个矩形. ...
- 《算法问题实战策略》-chaper15-计算几何-线段相交
这篇文章着力来讨论线段相交这一个问题. 给出两条线段,如何判断这两条线段相交? 如果这两条线段相交,如何求其交点? 线段相交问题通常由于其繁杂的情况种类而让人避而远之,在这里希望通过笔者的简化讨论希望 ...
- 并不对劲的CF1194E:Count The Rectangles
题意 有\(n\)(\(n\leq 5000\))个平行于x轴或平行于y轴的线段.求这些线段围成了多少个长方形.由多个长方形拼成的也算. 题解 考虑暴力的做法:先分别计算每条横着的线与哪些竖着的线有交 ...
- Codeforces 1197E Count The Rectangles(树状数组+扫描线)
题意: 给你n条平行于坐标轴的线,问你能组成多少个矩形,坐标绝对值均小于5000 保证线之间不会重合或者退化 思路: 从下到上扫描每一条纵坐标为y的水平的线,然后扫描所有竖直的线并标记与它相交的线,保 ...
- ccpc-1008-HDU5839Special Tetrahedron-计算几何
计算几何水题.暴力搞 注意力全部都在02那里,完全没想这道题! /*------------------------------------------------------------------ ...
- ACM-计算几何之Quoit Design——hdu1007 zoj2107
Quoit Design Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- uva-10112-计算几何
题意:给你一些点,求这些点组成的三角形面积最大,而且三角形内不能包含其他点 #include <iostream> #include <math.h> #include< ...
- Codeforces 1194E. Count The Rectangles
传送门 看到 $n<=5000$,直接暴力枚举左右两条竖线 然后考虑怎么计算高度在某个范围内,左端点小于等于某个值,右端点大于等于某个值的横线数量 直接用权值树状数组维护当前高度在某个区间内的横 ...
随机推荐
- 关于JS、JQ首行首列固定展示
当时遇见这个问题 是医院手麻系统大批量数据展示,由于是旧项目系统没有使用到前端的架构 只能使用JQ,JS, css完成 也谢谢给予我支持的同行们 固定首行数据: 采用函数的方式进行 JQ /** * ...
- Linux ln 命令
Linux 中的文件分为 Hard Link 和 Symbolic Link 两种.Hard Link 文件又被称为硬链接文件.实体链接文件,Symbolic Link 文件则常被称为符号链接.软链接 ...
- 【vue】------ 路由创建 ------ 【William】
路由常用的配置项: path:路由请求的路径 component:路由匹配成功后需要渲染的组件或者页面 tag:改变组件内部渲染的元素 假设组件内部渲染的是a标签 tag="li" ...
- Android:JNI与NDK(三)NDK构建的脚本文件配置
友情提示:欢迎关注本人公众号,那里有更好的阅读体验以及第一时间获取最新文章 本文目录 一.前言 本篇我们介绍Android.mk与CMakeLists.txt构建NDK的配置文件,我们知道目前NDK的 ...
- 限流降级神器,带你解读阿里巴巴开源 Sentinel 实现原理
Sentinel 是阿里中间件团队开源的,面向分布式服务架构的轻量级高可用流量控制组件,主要以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度来帮助用户保护服务的稳定性. 大家可能会问:Se ...
- 使用RedisMQ 做一次分布式改造
引言 熟悉TPL Dataflow博文的朋友可能记得这是个单体程序,使用TPL Dataflow 处理工作流任务, 在使用Docker部署的过程中, 有一个问题一直无法回避: 在单体程序部署的瞬间会有 ...
- Hibernate 框架
首先,我们先来了解一下什么是 Hibernate 框架. 什么是 Hibernate 框架? Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO ...
- 【Java笔记】【Java核心技术卷1】chapter3 D5运算符
package chapter3; import java.math.*; //引入数学类 //枚举类型 enum Size{SMALL,MEDIUM,LARGE}; public class D5运 ...
- 0x33 同余
目录 定义 同余类与剩余系 费马小定理 欧拉定理 证明: 欧拉定理的推论 证明: 应用: 定义 若整数 $a$ 和整数 $b$ 除以正整数 $m$ 的余数相等,则称 $a,b$ 模 $m$ 同余,记为 ...
- ubuntu安装伪分布式Hadoop3.1.2
作业要求:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/3223 本文是基于已经安装好的ubuntu环境上搭建伪分布式hadoop,在 ...