题目链接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. 智能手机中下一次被消灭的部件是电话卡和TF卡

    智能手机中下一次被消灭的部件是电话卡和TF卡. 侧滑实体键盘,实体拍照键,HDMI外接接口,实体切换双卡键,可拆卸后盖……这些都消亡了,被其更好的内在设计所取代.而电话卡和TF卡仍在使用.将来的智能手 ...

  2. C语言运算符的优先级与结合性

    结合性:左结合是从左到右依次执行,右结合是从右到左依次执行. 优先级 运算符 名称或作用 运算类型 结合方向 特点 1 () [] -> . 小括号运算符 下标运算符 指向结构成员运算符 结构成 ...

  3. JDBC——DriverManager驱动管理对象

    功能 1.注册驱动 注册驱动:告诉程序使用哪个驱动jar包 写代码使用:Class.forName("com.mysql.jdbc.Driver"); 查看源码 mysql-con ...

  4. mysql5.6创建账户不能本地登录

    1.通过xshell连接linux,命令登录mysql 2.创建一个新的库(其实创建不创建都可以) 3.创建账号权限 创建账号luffy 密码luffy 针对库luffy所有权限,允许任何人远程登录 ...

  5. 洛谷P1147 连续自然数和

    https://www.luogu.org/problem/P1147 #include<bits/stdc++.h> using namespace std; int main(){ i ...

  6. 《深入理解Java虚拟机》读书笔记五

    第六章 类文件结构 1.无关性的基石 各种不同平台的虚拟机与所有平台都统一使用程序存储格式——字节码是构成平台无关的基石. 实现语言无关性的基础仍然是虚拟机和字节码存储格式,Java虚拟机不和包括Ja ...

  7. [P4550] 收集邮票 - 概率期望,dp

    套路性地倒过来考虑,设\(f[i]\)表示拥有了\(i\)种票子时还需要多少次购买,\(g[i]\)表示还需要多少钱 推\(g[i]\)递推式时注意把代价倒过来(反正总数一定,从顺序第\(1\)张开始 ...

  8. 删除空目录命令 - rmdir

    (1) 命令名称:rmdir (2) 英文原意:remove empty directories (3) 命令所在路径:/bin/rmdir (4) 执行权限:所有用户 (5) 功能描述:删除空目录( ...

  9. 使用JavaMail发送邮箱详解

    package com.gqz.forfuture.email; import java.util.Date; import java.util.Properties; import javax.ma ...

  10. k线、指标绘制

    我接触的绘制有两种:gdi+和qt绘图.可以灵活的绘制任何想要的东西. 先上效果图吧. 如下:基于gdi+的股指和股票的绘制.上面是沪深成分股实时生成的股票指数走势,下面是IF主力走势和开平仓位置. ...