题目链接https://codeforces.com/gym/102361/problem/A

题意:给定二维平面上的\(n\)个点,\(q\)次询问,每次加入一个点,询问平面上有几个包含该点的直角三角形。

分析:这是一篇鸽了很久的题解,主要原因就是现场赛的时候这题惨遭卡常,锅++。现在回过头来想这题,主要问题出在现场赛时误判了\(map\)的时间复杂度,把极角排序的正确想法成功叉掉,以及现场赛时候的共线计数使用了\(gcd\),使得整体复杂度上升。(但还是有大佬拿gcd思想过了,我太菜了)现在学了一种共线计数的新想法,只需要重载就能实现,于是再用\(map\)来写一写这道题。。。

本题思路不难,将直角三角形分为两类,一类是以新加入点为直角顶点的直角三角形,另一类新加入点不作直角顶点。第一种情况,我们将新加入点与原有点之间构成的所有向量加入\(map\),然后通过点积为零的性质查找垂直的向量个数。(会计数两次,要除以二)另一类采取离线操作,我们将每个原有点当作直角顶点遍历,并将该点与另外原有点构成的向量加入\(map\),更新\(q\)个新加入点的直角三角形数量即可。

AC代码

#pragma GCC target("avx")
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define SIZE 2010
#define rep(i, a, b) for (int i = a; i <= b; ++i)
#define ll long long
using namespace std;
struct Point {
ll x, y;
Point() {}
Point(ll a, ll b) :x(a), y(b) {}
Point base() const{
if (x < 0 || (x == 0 && y < 0))return Point(-x, -y);
return *this;
}
bool operator<(const Point& b)const {
Point p1 = base(); Point p2 = b.base(); //如果共线,考虑是相同的索引
return p1.x * p2.y < p1.y * p2.x;
}
void input() { scanf("%lld %lld", &x, &y); }
}p[SIZE];
Point operator *(Point a, ll t) { return Point(a.x * t, a.y * t); } //向量数乘
Point operator +(Point a, Point b) { return Point(a.x + b.x, a.y + b.y); } //向量加法
Point operator -(Point a, Point b) { return Point(b.x - a.x, b.y - a.y); } //向量减法
Point operator / (Point a, ll p) { return Point(a.x / p, a.y / p); } //向量数乘的除法形式
double Polarangle(Point a) { return atan2(a.y, a.x); }
ll __gcd(ll a, ll b) { return b == 0 ? a : __gcd(b, a % b); }
int n, q, cnt = 1;
map<Point, int> MAP;
int main() {
scanf("%d %d", &n, &q);
int m = q;
vector<Point> vec(q + 1);
vector<int> res(q + 1);
rep(i, 1, n) p[i].input();
while (m--) {
int ans = 0; Point tp; tp.input();
vec[cnt] = tp;
rep(i, 1, n) {
Point tmp = p[i] - tp;
++MAP[tmp];
}
for (auto it : MAP) {
Point tmp(-it.first.y, it.first.x);
if (MAP.count(tmp)) ans += MAP[tmp] * it.second;
}
res[cnt++] = ans / 2;
MAP.clear();
}
rep(i, 1, n) {
MAP.clear();
rep(j, 1, n) {
if (i == j) continue;
MAP[p[j] - p[i]]++;
}
rep(j, 1, q) {
Point tp = vec[j] - p[i];
tp = Point(-tp.y, tp.x);
res[j] += MAP.count(tp) ? MAP[tp] : 0;
}
}
rep(i, 1, q) printf("%d\n", res[i]);
}

Codeforces Gym 102361A Angle Beats CCPC2019秦皇岛A题 题解的更多相关文章

  1. Codeforces Round #524 (Div. 2)(前三题题解)

    这场比赛手速场+数学场,像我这样读题都读不大懂的蒟蒻表示呵呵呵. 第四题搞了半天,大概想出来了,但来不及(中途家里网炸了)查错,于是我交了两次丢了100分.幸亏这次没有掉rating. 比赛传送门:h ...

  2. codeforces Gym 100187L L. Ministry of Truth 水题

    L. Ministry of Truth Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/p ...

  3. Codeforces Gym 100610 Problem E. Explicit Formula 水题

    Problem E. Explicit Formula Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10 ...

  4. Codeforces Gym 100342H Problem H. Hard Test 构造题,卡迪杰斯特拉

    Problem H. Hard TestTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100342/at ...

  5. Gym102361A Angle Beats(直角三角形 计算几何)题解

    题意: \(n\)个点,\(q\)个询问,每次问包含询问点的直角三角形有几个 思路: 代码: #include<bits/stdc++.h> using namespace std; co ...

  6. Codeforces Gym 100523C C - Will It Stop? 水题

    C - Will It Stop?Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/ ...

  7. Codeforces Round #796 (Div. 2)(A~E题题解)

    文章目录 原题链接: A.Cirno's Perfect Bitmasks Classroom 思路 代码 B.Patchouli's Magical Talisman 思路 代码 C.Manipul ...

  8. Codeforces Round #530 (Div. 2) (前三题题解)

    总评 今天是个上分的好日子,可惜12:30修仙场并没有打... A. Snowball(小模拟) 我上来还以为直接能O(1)算出来没想到还能小于等于0的时候变成0,那么只能小模拟了.从最高的地方进行高 ...

  9. Codeforces Gym 101252D&&floyd判圈算法学习笔记

    一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1. 题解:都不到100天就AFO了才来学这floyd判圈 ...

随机推荐

  1. 野路子码农(5)Python中的装饰器,可能是最通俗的解说

    装饰器这个名词一听就充满了高级感,而且很多情况下确实也不常用.但装饰器有装饰器的好处,至少了解这个对装逼还是颇有益处的.网上有很多关于装饰器的解说,但通常都太过“循序渐进”,有的还会讲一些“闭包”之类 ...

  2. Hackintosh相关资源站

    猫叔博客 https://www.maoshu.cc/ 大神RehabMan https://bitbucket.org/RehabMan/ dsdt/ssdt打补丁译文 https://blog.c ...

  3. 转: Struts2中拦截器与过滤器的区别及执行顺序

    当接收到一个httprequest , a) 当外部的httpservletrequest到来时 b) 初始到了servlet容器 传递给一个标准的过滤器链 c) FilterDispatecher会 ...

  4. day02_1hibernate

    对象状态与一级缓存 一.对象缓存状态的介绍: ①在使用hibernate时对象的三种状态:(代码如下) 瞬时状态 :没有与session关联,没有主键OID标识(主键的OID指的是对象id,在配置文件 ...

  5. 简写函数字面量(function literal)

    如果函数的参数在函数体内只出现一次,则可以使用下划线代替: val f1 = (_: Int) + (_: Int) //等价于 val f2 = (x: Int, y: Int) => x + ...

  6. Oracle Linux安装

    注:Oracle11gR2 X64安装 一.环境准备 安装包: 2.CentOS-7-x86_64-DVD-1511.iso 3.linux.x64_11gR2_database_1of2.zip l ...

  7. echart --toolbox

    1.自定义的toolbox 消息回调 toolbox: { show: true, itemSize: 32, borderColor: '#0cb1b6', borderWidth: 1, bord ...

  8. 如何去官网上下载tomcat的linux版本

    1.首先进入官网,进入如下位置 2.进入bin文件夹中下载: 原文链接:https://blog.csdn.net/zdb292034/article/details/82433072

  9. laravel-middleware中间件常用使用方法

    介绍 中间件提供了一种方便的机制过滤进入应用程序的 HTTP 请求.例如,Laravel 包含一个中间件,验证您的应用程序的用户身份验证.如果用户未被认证,中间件会将用户重定向到登录界面.然而,如果用 ...

  10. Mysql使用事务

    DECLARE t_error INTEGER DEFAULT 0; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1; START TR ...