【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$,直接暴力枚举左右两条竖线 然后考虑怎么计算高度在某个范围内,左端点小于等于某个值,右端点大于等于某个值的横线数量 直接用权值树状数组维护当前高度在某个区间内的横 ...
随机推荐
- Apache Ignite 学习笔记(6): Ignite中Entry Processor使用
之前的文章我们其实已经用到了两种不同的方式访问Ignite中的数据.一种方式是第一篇文章中提到通过JDBC客户端用SQL访问数据,在这篇文章中我们也会看到不使用JDBC,如何通过Ignite API用 ...
- 14. 流、文件和IO
前言 InputStream/OutStream流用来处理设备之间的数据传输 Java.io 包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io 包中的流支持 ...
- Android开发进阶——自定义View的使用及其原理探索
在Android开发中,系统提供给我们的UI控件是有限的,当我们需要使用一些特殊的控件的时候,只靠系统提供的控件,可能无法达到我们想要的效果,这时,就需要我们自定义一些控件,来完成我们想要的效果了.下 ...
- codeforces 327 B. Hungry Sequence
题目链接 题目就是让你输出n个数的序列,要保证该序列是递增的,并且第i个数的前面不能保护它的约数,我直接先对前100000的素数打表,然后输出前n个,so easy. //cf 191 B #incl ...
- JWT token 跨域认证
JSON Web Token(缩写 JWT),是目前最流行的跨域认证解决方案. session登录认证方案:用户从客户端传递用户名.密码等信息,服务端认证后将信息存储在session中,将sessio ...
- 给最近正在找工作(iOS)的朋友一些建议/经验
众所周知, iOS开发找工作越来越难, 企业要求越来越高,一方面是资本寒冬期+七八月是企业招人淡季, 另外一方面也是iOS市场饱和.最近有出去看新机会, 所以下面记录一下面试XimalayaFM的大概 ...
- 记一次python时间格式转换遇到的坑
需求:拿到指定格式的时间的前一天的时间,如果今天是月初,年初,自动转换,比如:输入时间是:2019-06-27 23:59:59输出时间是:2019-06-26 23:59:59 之前用datetim ...
- 微服务SpringCloud之Spring Cloud Config配置中心SVN
在回来的路上看到一个个的都抱着花,吃了一路的狗粮,原本想着去旁边的工业园里跑跑步呢,想想还是算了,人家过七夕,俺们过巴西.上一博客学习了Spring Cloud Config使用git作为配置中心,本 ...
- 前端笔记之微信小程序(四)WebSocket&Socket.io&摇一摇案例&地图|地理位置
一.WebSocket概述 http://www.ruanyifeng.com/blog/2017/05/websocket.html Workerman一款开源高性能异步PHP socket即时通讯 ...
- 【Java例题】6.1 进制转换
1.进制转换.输入一个某种进制的整数,将其转换为其它进制的整数.说明:仅考虑十.二.八和十六进制. package chapter6; import java.util.*; public class ...