【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$,直接暴力枚举左右两条竖线 然后考虑怎么计算高度在某个范围内,左端点小于等于某个值,右端点大于等于某个值的横线数量 直接用权值树状数组维护当前高度在某个区间内的横 ...
随机推荐
- c&c服务器(command and control server)
远程命令和控制服务器,目标机器可以接收来自服务器的命令,从而达到服务器控制目标机器的目的.该方法常用于病毒木马控制被感染的机器.
- logging模块 旗舰版
函数式简单配置 import logging logging.debug('debug message') logging.info('info message') logging.warning(' ...
- 使用Java 编写FTP中的长传文件和下载文件
实现FTP文件上传与下载可以通过以下两种种方式实现(不知道还有没有其他方式,),分别为:1.通过JDK自带的API实现:2.通过Apache提供的API是实现. 第一种方法:通过JDK自带的API实现 ...
- Vue2.0仿饿了么webapp单页面应用
Vue2.0仿饿了么webapp单页面应用 声明: 代码源于 黄轶老师在慕课网上的教学视频,我自己用vue2.0重写了该项目,喜欢的同学可以去支持老师的课程:http://coding.imooc.c ...
- 后端基于方法的权限控制--Spirng-Security
后端基于方法的权限控制--Spirng-Security 默认情况下, Spring Security 并不启用方法级的安全管控. 启用方法级的管控后, 可以针对不同的方法通过注解设置不同的访问条件: ...
- spark学习(10)-RDD的介绍和常用算子
RDD(弹性分布式数据集,里面并不存储真正要计算的数据,你对RDD的操作,他会在Driver端转换成Task,下发到Executor计算分散在多台集群上的数据) RDD是一个代理,你对代理进行操作,他 ...
- 关于JVM内存溢出的原因分析及解决方案探讨
前言:JVM中除了程序计数器,其他的区域都有可能会发生内存溢出. 0.什么是内存溢出 当程序需要申请内存的时候,由于没有足够的内存,此时就会抛出OutOfMemoryError,这就是内存溢出. 1. ...
- 最简单的DWR例子
什么是DWR? DWR是一个Open Source的 java项目.DWR可以让JavaScript调用运行在Web服务器里面的JAVA程序.简单一点或者专业一点就是Easy AJAX for JAV ...
- 使用Qt5+CMake实现图片的区域选择(附源码)
近期研发涉及到了图片的区域选择,找来一些资料一直不能很满意,所以自己实现了一个. 实现步骤如下.源码可以点击ImageAOI获取. 如下资料来自源码的README. ImageAOI (XLabel) ...
- 用xshell链接虚拟机上的linux
[步骤]一.安装VMware直接点击下一步即可 二.安装linux下载CentOS,在VMware中安装,这个网上有很多教程,这里就不赘述了. 三.配置要想连接上xshell,需要配置IP,将Linu ...