CF

# 题意

总共有5000条线段,这些线段要么水平,要么垂直,问这些线段组成了多少矩形。

# 思路

这是一个n*n*(log)的思路

自己一开始想着枚举两条垂直边,想着怎么把水平的边插入,再进行冗斥等数出与两边都相交的数量。但是做不出来。

后来学习了如图的思路。

我们枚举垂直边,对于来说,因为三条红线与有交点,我们就标记三条红线。然后枚举剩下垂直边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 数据结构算几何的更多相关文章

  1. HDU 5128.The E-pang Palace-计算几何

    The E-pang Palace Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Othe ...

  2. Educational Codeforces Round 68 E. Count The Rectangles

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

  3. 《算法问题实战策略》-chaper15-计算几何-线段相交

    这篇文章着力来讨论线段相交这一个问题. 给出两条线段,如何判断这两条线段相交? 如果这两条线段相交,如何求其交点? 线段相交问题通常由于其繁杂的情况种类而让人避而远之,在这里希望通过笔者的简化讨论希望 ...

  4. 并不对劲的CF1194E:Count The Rectangles

    题意 有\(n\)(\(n\leq 5000\))个平行于x轴或平行于y轴的线段.求这些线段围成了多少个长方形.由多个长方形拼成的也算. 题解 考虑暴力的做法:先分别计算每条横着的线与哪些竖着的线有交 ...

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

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

  6. ccpc-1008-HDU5839Special Tetrahedron-计算几何

    计算几何水题.暴力搞 注意力全部都在02那里,完全没想这道题! /*------------------------------------------------------------------ ...

  7. ACM-计算几何之Quoit Design——hdu1007 zoj2107

    Quoit Design Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  8. uva-10112-计算几何

    题意:给你一些点,求这些点组成的三角形面积最大,而且三角形内不能包含其他点 #include <iostream> #include <math.h> #include< ...

  9. Codeforces 1194E. Count The Rectangles

    传送门 看到 $n<=5000$,直接暴力枚举左右两条竖线 然后考虑怎么计算高度在某个范围内,左端点小于等于某个值,右端点大于等于某个值的横线数量 直接用权值树状数组维护当前高度在某个区间内的横 ...

随机推荐

  1. 1A2B

    玩了玩www.syscan.org的小游戏,第三关是一个1A2B的问题,写个小脚本爆破一波,同时分享下脚本(把数固定到代码里了,要在别处用的自己改吧). #-*-coding:utf8;-*- #qp ...

  2. 【Android】Jetpack中的ViewModel:自动保存页面数据

    目录 ViewModel 简介 ViewModel的使用方法 ViewModel 简介   ViewModel 允许数据在配置更改(如屏幕旋转)后仍然存在,使用 ViewModel 可以免去开发者花费 ...

  3. CSS开启硬件加速来提高网站性能

    原文永久链接 CSS animations, transforms 以及 transitions 不会自动开启GPU加速,而是由浏览器的缓慢的软件渲染引擎来执行. 那我们怎样才可以切换到GPU模式呢, ...

  4. jenkins弱口令漏洞

    jenkins弱口令漏洞 一.漏洞描述 通过暴力破解管理控制台,如果爆破成功,可获得后台管理权限.操作后台,后台可通过脚本命令行功能执行系统命令,如反弹shell等,低权限可以通过创建控制台输出方式执 ...

  5. RocketMQ中Broker的启动源码分析(一)

    在RocketMQ中,使用BrokerStartup作为启动类,相较于NameServer的启动,Broker作为RocketMQ的核心可复杂得多 [RocketMQ中NameServer的启动源码分 ...

  6. 01-Spring Security框架学习--入门(二)

    一.入门案例 Spring Security 自定义登录界面 通过之前的一节 01-Spring Security框架学习--入门(一)的简单演示,Spring security 使用框架自带的登录界 ...

  7. jquery EasyUi 添加节点、展开所有节点、默认选中第一个节点

    感觉easyUi 的树用起来不如 Ext 的树方便,首先,root节点不太好自定义, 异步加载时,只能通过后台判断生成root节点,但是这样一来有一个问题,就是第一次访问界面时, 树的初始化比较慢,大 ...

  8. Eclipse 连接不上 hadoop 的解决办法

    先说一下我的情况,集群的 hadoop 是 1.0.4 ,之后在虚拟机上搭建了最新稳定版 1.2.1 之后,Eclipse 插件始终连接不上. 出现 Error: Call to 192.168.1. ...

  9. python_Tensorflow学习(三):TensorFlow学习基础

    一.矩阵的基本操作 import tensorflow as tf   # 1.1矩阵操作 sess = tf.InteractiveSession() x = tf.ones([2, 3], &qu ...

  10. 使用阿里云oss

    写这篇博文的原因是公司有个项目需要用到阿里云来存放用户头像文件.后期软件安装版本也可能需要存进去,然后折腾了两天终于摸熟了一点皮毛,在这里给大家简单介绍下. 一.初识对象存储oss 1.进入阿里云控制 ...