小兔的话

欢迎大家在评论区留言哦~

AtCoder Beginner Contest 168


A - ∴ (Therefore)


B - ... (Triple Dots)


C - : (Colon)


D - .. (Double Dots)


E - ∙ (Bullet)

简单题意

小兔捕获了 \(N\) 条不同的沙丁鱼,第 \(i\) 条沙丁鱼的 美味程度香味程度 分别是 \(A_i\) 和 \(B_i\)

她想在这些沙丁鱼中选择 一条 或者 多条 放入冷冻箱;但是必须保证沙丁鱼的选择是合格的

(合格的定义:其中的任意两条沙丁鱼 \(i\) 和 \(j\) 都不满足 \(A_i \times A_j + B_i \times B_j = 0\))

小兔想知道有多少种选择沙丁鱼的方法(选择的沙丁鱼的集合相同,算同一种方法),答案对 \(1e9 +7\) 取模

数据范围

\(1 \leq N \leq 2 \times 10^5\)

\(-10^{18} \leq A_i, B_i \leq 10^{18}\)

知识点

  • 数学知识

    • 最大公约数 \(\mathrm{gcd}\)
    • 快速幂
  • STL
    • map
    • pair

分析

需要不满足的式子与 \(i\) 和 \(j\) 的关系太大了,不妨化简一下:

\[A_i \times A_j + B_i \times B_j = 0 \to A_i \times A_j = - B_i * B_j \to \frac{A_i}{B_i} = - \frac{B_j}{A_j}
\]

我们可以把 \(\frac{A_i}{B_i}\) 相同的分成一组,统计出属于这一组的沙丁鱼的数量,再把 \(\frac{A_i}{B_i}\) 和 \(- \frac{B_j}{A_j}\) 的两组分成一对,这一对肯定是互相满足的(就是 \(C\) 与 \(D\) 是一对,反过来 \(D\) 肯定与 \(C\) 是一对,\(D\) 不会和其它成为一对)

我们计算每一对里的选择方案,把所有的选择方案数乘起来再 减一(排除全部不选的情况),就是最终的答案了

如何计算每一对里的选择方案呢?

可以先计算每一对中每组的选择方案,设属于这一组的沙丁鱼有 \(s\) 条,选择沙丁鱼的方案数就是 \(2^s\)(每条鱼有 被选择不被选择 \(2\) 种情况)

那么每一对的方案数就是 \(s_1 + s_2 - 1\)

  • 因为其中的两组是不能同时选的,所以是 \(+\) 而不是 \(\times\)
  • 因为在统计 \(s_1\) 被选的时候,\(s_2\) 一定是不选的;同理,在统计 \(s_2\) 被选的时候,\(s_1\) 一定是不选的;需要减去这 \(2\) 种多算的情况;又因为 \(2\) 组都不选也是 \(1\) 种合格的情况,所以又要加上 \(1\) 种情况,所以是 \(+1\)

代码

#include <cstdio>
#include <map>
#include <utility>
using namespace std;
#define int long long int Gcd(int u, int v) { return (v == 0) ? u : Gcd(v, u % v); }
int Max(int u, int v) { return (u > v) ? u : v; }
int Min(int u, int v) { return (u < v) ? u : v; } int rint()
{
int x = 0, fx = 1; char c = getchar();
while (c < '0' || c > '9') { fx ^= ((c == '-') ? 1 : 0); c = getchar(); }
while ('0' <= c && c <= '9') { x = (x << 3) + (x << 1) + (c ^ 48); c = getchar(); }
if (!fx) return -x;
return x;
} int qpow(int u, int v, int Mod)
{
int ans = 1; u %= Mod;
while (v)
{
if (v & 1) ans = ans * u % Mod;
u = u * u % Mod; v >>= 1;
}
return ans;
} const int MOD = 1e9 + 7;
const int MAX_n = 2e5; int n, ans = 1, sum = 0;
int A[MAX_n + 5];
int B[MAX_n + 5];
map<pair<int, int>, int> G;
map<pair<int, int>, bool> vis; signed main()
{
n = rint();
for (int i = 1; i <= n; i++)
{
A[i] = rint(), B[i] = rint();
if (A[i] == 0 && B[i] == 0)
{
++sum; --i; --n; continue;
}
int temp = Gcd(A[i], B[i]);
A[i] /= temp; B[i] /= temp;
if (A[i] < 0) { A[i] = -A[i]; B[i] = -B[i]; }
++G[make_pair(A[i], B[i])];
}
for (int i = 1; i <= n; i++)
{
pair<int, int> now = make_pair(A[i], B[i]);
if (-B[i] < 0) { B[i] = -B[i]; A[i] = -A[i]; }
pair<int, int> other = make_pair(-B[i], A[i]);
if (vis[now] || vis[other]) continue;
vis[now] = vis[other] = true;
ans = ans * ((qpow(2, G[now], MOD) + qpow(2, G[other], MOD) - 1) % MOD) % MOD;
}
printf("%lld\n", (ans - 1 + sum + MOD) % MOD);
return 0;
}

F - . (Single Dot)


题解 AtCoder Beginner Contest 168的更多相关文章

  1. AtCoder Beginner Contest 168

    比赛链接:https://atcoder.jp/contests/abc168/tasks A - ∴ (Therefore) 题意 给出一个由数字组成的字符串 $s$,要求如下: 如果 $s$ 以 ...

  2. Atcoder Beginner Contest 168 D - .. (Double Dots) (BFS)

    题意:有\(n\)个房间,在这些房间中两两连\(m\)次条边,问除了第一个房间,其他房间走到第一个房间的最短路径,输出这个房间所连的上一个房间,如果走不到,输出\(no\). 题解:刚开始我写了一个d ...

  3. [题解] Atcoder Beginner Contest ABC 270 G Ex 题解

    点我看题 G - Sequence in mod P 稍微观察一下就会发现,进行x次操作后的结果是\(A^xS+(1+\cdots +A^{x-1})B\).如果没有右边那一坨关于B的东西,那我们要求 ...

  4. [题解] Atcoder Beginner Contest ABC 265 Ex No-capture Lance Game DP,二维FFT

    题目 首先明确先手的棋子是往左走的,将其称为棋子1:后手的棋子是往右走的,将其称为棋子2. 如果有一些行满足1在2右边,也就是面对面,那其实就是一个nim,每一行都是一堆石子,数量是两个棋子之间的空格 ...

  5. AtCoder Beginner Contest 154 题解

    人生第一场 AtCoder,纪念一下 话说年后的 AtCoder 比赛怎么这么少啊(大雾 AtCoder Beginner Contest 154 题解 A - Remaining Balls We ...

  6. AtCoder Beginner Contest 153 题解

    目录 AtCoder Beginner Contest 153 题解 A - Serval vs Monster 题意 做法 程序 B - Common Raccoon vs Monster 题意 做 ...

  7. AtCoder Beginner Contest 177 题解

    AtCoder Beginner Contest 177 题解 目录 AtCoder Beginner Contest 177 题解 A - Don't be late B - Substring C ...

  8. KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解

    KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解 哦淦我已经菜到被ABC吊打了. A - Century 首先把当前年 ...

  9. AtCoder Beginner Contest 184 题解

    AtCoder Beginner Contest 184 题解 目录 AtCoder Beginner Contest 184 题解 A - Determinant B - Quizzes C - S ...

随机推荐

  1. 链表中倒数第k个节点 双指针

  2. 【GIS风暴】30米分辨率地表覆盖数据GlobeLand30原始数据集简介及下载地址

    数据集预览: GlobeLand30是30米空间分辨率全球地表覆盖数据,目前可供下载使用的有3年的数据:2000-2010-2020,本文主要讲述GlobeLand30的官网下载地址和数据集简介. 数 ...

  3. 只需5分钟!一文读懂CSS布局(二) -- flex布局

    目录 简介 基本概念 容器属性 1. flex-direction 测试代码 2. flex-wrap 3. flex-flow 4. justify-content 5. align-items 6 ...

  4. Oracle的Rman差异增量备份

    所谓增量备份,顾名思义即是每次备份操作那些发生了"变化"的数据块.在RMAN增量备份中有两种:Differential(差异备份)和Cumulative(增量备份)方式.由于需求这 ...

  5. 自动机器学习(AutoML)

    自动机器学习(AutoML) 不再需要苦恼于学习各种机器学习的算法 目录: 一.为什么需要自动机器学习 二.超参数优化 Hyper-parameter Optimization 三.元学习 Meta ...

  6. nvGRAPH三角形计数和遍历示例

    nvGRAPH三角形计数和遍历示例 #include " stdlib.h" #include" inttypes.h" #include" stdi ...

  7. TensorRT 3:更快的TensorFlow推理和Volta支持

    TensorRT 3:更快的TensorFlow推理和Volta支持 TensorRT 3: Faster TensorFlow Inference and Volta Support 英伟达Tens ...

  8. 读HikariCP源码学Java(二)—— 因地制宜的改装版ArrayList:FastList

    前言 如前文所述,HikariCP为了提高性能不遗余力,其中一个比较特别的优化是它没有直接使用ArrayList,而是自己实现了FastList,因地制宜,让数组的读写性能都有了一定程度的提高. 构造 ...

  9. 『动善时』JMeter基础 — 45、脚本录制工具Badboy介绍

    目录 1.Badboy软件介绍 2.Badboy下载 3.Badboy安装 4.Badboy界面介绍 (1)菜单栏: (2)工具栏: (3)左下角界面视图: 1.Badboy软件介绍 Badboy是一 ...

  10. css--常见左右盒子高度自适应布局

    前言 前端开发工程师最基础的技能要求是根据 ui 设计稿还原网页,这就缺少不了必要的网页布局,首先看下最近小伙伴问我的一个问题,他说一个网页有左右两个部分,左右两个部分的高度都不固定,要使得右部分的宽 ...