E - ∙ (Bullet)

题意:

有 N 条不同的沙丁鱼,第 i 条沙丁鱼的 美味程度 和 香味程度 分别是 Ai 和 Bi。
在这些沙丁鱼中选择 一条 或者 多条 放入冷冻箱,但是必须保证沙丁鱼的选择是合格的。
(合格的定义:其中的任意两条沙丁鱼 i 和 j 都不满足 Ai × Aj + Bi × Bj = 0。)

问多少种选择沙丁鱼的方法(选择的沙丁鱼的集合相同,算同一种方法),答案对 1e9+7 取模。

数据范围:

1 ≤ N ≤ 2 ×

 ≤ Ai​, Bi​ ≤ 

思路:

参考博客

首先将公式化简下:Ai × Aj + Bi × Bj = 0 → Ai × Aj = −Bi ∗ Bj →   。
我们可以把 Ai / Bi 相同的分成一组,统计出属于每组鱼的数量,再把 Ai / Bi 和 −Bi/  Ai 的两组看成一对,这两组肯定是相对的。也就是说,这两组是不能同时选的,我们把每一对能选的方案数求出来后,将所有对的方案数相乘再减1(排除全部不选的情况)就是总方案数。

每一对的方案数如何计算呢——
首先预处理出该对中两个组中鱼的个数后,先算出每个组内部的方案数,假设第一组(值为 A / B )鱼的个数为 s1,那么该组内部方案数为 (相当于每个鱼都有选/不选两种选择)。同理求出另一组(值为 -B / A )的方案数。所以该对的方案数为

说明:
1. 因为其中的两组是不能同时选的,所以是 + 而不是 ×;
2. 因为在统计 s1 被选的时候,s2 一定是不选的;同理,在统计 s2 被选的时候,s1 一定是不选的;所以不需要考虑各自组都不取的这 2 种多算的情况;又因为 2 组一条鱼都不选也是 1 种合格的情况,所以又要加上 1 种情况,所以是最后需要 -2 + 1 = -1。
比如:s1=s2=2,总共有7种:2个(1,0),2个(0,1),1个(2,0),1个(0,2),最后算上(0,0)。

实现:

1. 用 mp<PII,int> 记录值为 a / b 的组中鱼个数。PII 存的是化简后的 a / b 的分子和分母。通过求出原分子分母的最大公因数 d 后,让分子分母都除以 d 来化简。注意 a,b 的范围,可能为 0 或负数——(1)如果a=b=0,d=0,取了它以后,别的都不能取,所以需要把每条这样的鱼单独归为一组单独放,只要加上这种鱼的个数s即可;(2)如果是 a / b 的值负数,为了我们之后在mp中找值为 -b / a 更方便,所以我们统一将存入的为负数的 a / b 的负号放在分母的位置,即 PII 的 second 位置。也就是说你所存入的(a,b)一定是第一个数为正,第二个数为负。

2. 遍历每一组,在遍历时用快速幂算出这一组的方案数 d 后,在 mp 中找与之相对的组,即存入的 PII 为(b,-a)的组(这里也是有负号位置的统一处理的)。再让 d 加上该组的方案后 -1 即可。得出一对的方案数。

3. 算出所有对的方案数的乘积后,最后-1+s(-1减的是所有鱼都不选的情况)即为最终答案。

Code:

参考代码

#include<bits/stdc++.h>
using namespace std;const double PI = 4.0 * atan(1.0);
//#define PI 3.14159265358979
#define x first
#define y second
#define int long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);const int dx[] = { 1,-1,0,0 }, dy[] = { 0,0,1,-1 };
const int N = 100010, INF = 0x3f3f3f3f, mod = 1e9 + 7;
typedef pair<int, int>PII;int n;
map<PII, int>mp;//快速幂
int qmi(int a, int k)
{int res = 1;  while (k){if (k & 1)res = res * a % mod;a = a * a % mod;k >>= 1;}return res;
}void solve()
{cin >> n;int s = 0;for (int i = 0; i < n; i++){int a, b;cin >> a >> b;int d = __gcd(a, b);                               //计算两数的最大公因数,方便求a/bif (d == 0)                                         //d=0说明a,b都为0,只能单独为一组放,用s记录这样的鱼的个数{s++;continue;}a /= d, b /= d;                                     //得出化简后的a/b的分子分母if (a < 0)a = -a, b = -b;                          //为了使得所存的分子,分母负数的位置统一,所以将负数的负号放在分母(b)的位置mp[{a, b}]++;                                       //累计ai/bi为该值的鱼的个数}int ans = 1;for (auto it : mp)                                       //单独遍历每一组(a/b不同的组){if (it.y == 0)continue;int a = it.x.x, b = it.x.y;                           //摘出该组a/b的分子a,分母bint d = qmi(2, mp[{a, b}]);                           //计算该组内部可选的方案数,该组鱼的个数mp[{a,b}],个数为2^p[{a,b}]b = -b;                                              //与之相对的组,分母为-bif (b < 0)a = -a, b = -b;                         //同样为了负数位置的一致性,如果是负数,就将负号赋给分母aif (mp.count({ b,a })){d = (d + qmi(2, mp[{b, a}]) - 1) % mod;            //记录与之相对的组的内部种类数。-1=-2+1:-2是先去掉两组中各自拥有的都不选的情况,在算上的+1是两组都不选的情况mp[{b, a}] = 0;}ans = ans * d % mod;                               //每一对的个数的乘积}ans = (ans - 1 + s + mod) % mod;                     //减1是减去所有于都不选的情况cout << ans << endl;
}signed main()
{IOS;//int t;int t = 1;//cin >> t;while (t--){solve();}return 0;
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
吐槽:题目注意点:

1.整体思路就是将n个鱼根据ai/bi先分成几对,每一对分别算,每一对里的两个组再分别计算,再合并。
2.最后还包括一些细节处理。比如用map存对时负号位置的统一化。还有其中的+1,-1的理解。

AtCoder - ABC 168 - E(数学推理)相关推荐

  1. 关于鬼谷子的数学推理题

    之前在网上看到一个小学奥数级别的题目如下: 一天鬼出了这道题目:他从2到99中选出两个不同的整数,把积告诉孙,把和告诉庞: 庞说:我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数是什么. 孙 ...

  2. 论文浅尝 | NumNet: 一种带有数学推理的机器阅读理解模型

    论文笔记整理:吴林娟. 来源:EMNLP2019 论文链接:https://arxiv.org/pdf/1910.06701.pdf 开放源码:https://github.com/ranqiu92/ ...

  3. AtCoder ABC 250 总结

    AtCoder ABC 250 总结 总体 连续若干次一样的结果:30min 切前 4 题,剩下卡在 T5 这几次卡在 T5 都是一次比一次接近, 什么 dp 前缀和打挂,精度被卡,能水过的题连水法都 ...

  4. PLM是做题家吗?一文速览预训练语言模型数学推理能力新进展

    ©作者 | 张北辰 单位 | 中国人民大学高瓴人工智能学院 数学推理能力是人类智能的一项非常重要又富有挑战性的能力.尽管在各类自然语言相关的理解和生成任务等中取得了良好的效果,预训练语言模型可以准确地 ...

  5. Atcoder abc 233 题解

    Atcoder abc 233 题解 A 10yen Stamp 答案就是两个数字的差/10之后上取整 记得判断res=0的情况就可以了 c++代码 #include<iostream> ...

  6. AtCoder - ABC 167 - E(数学推理+组合数)

    E - Colorful Blocks 题意: 有 m 种颜色,给 n 个方块染色,可以不使用所有颜色,要求最多有 k 对相邻方块同色.问染色的总情况,最终结果模  998244353. 数据范围: ...

  7. OpenAI推出数学推理证明模型,推理结果首次被数学家接受

    大数据文摘出品 作者:牛婉杨 今年6月,OpenAI发布一款强大的文本生成模型GPT-3,不少网友迅速上手用了起来,有人用它写食谱.写歌词,甚至有人用它写博客,愣是以假乱真登上了新闻平台技术板块热榜第 ...

  8. leetcode 292. Nim Game | 292. Nim 游戏(DP->数学推理)

    题目 https://leetcode-cn.com/problems/nim-game/ 题解 本题实际上是一个需要分析的数学题.如果第一时间没有发现规律的话,可以尝试先用递归法,暴力输出前几个,观 ...

  9. 中山大学HCP Lab系列论文:AI解题新突破,神经网络推开数学推理大门

    ©作者 | 机器之心编辑部 来源 | 机器之心 本文对中山大学人机物智能融合实验室(HCP Lab)在数学解题领域的一系列研究进行了简要介绍,这些工作主要由 HCP 实验室秦景辉博士等人完成.该系列工 ...

  10. AtCoder ABC 127F Absolute Minima

    题目链接:https://atcoder.jp/contests/abc127/tasks/abc127_f 题目大意 初始状态下$f(x) = 0$,现在有 2 种模式的询问,第一种以"1 ...

最新文章

  1. Linux下 su命令与su - 命令的区别
  2. 集合,stack,queue,dictionary,ArrayList,listT
  3. 加强数据中心安全的六条措施
  4. 涂格子游戏html,网页版方格贪吃蛇游戏html源码分享
  5. publiccms实现首页菜单栏下拉的方法
  6. javascript中对变量类型的推断
  7. OJ1017: 表面积和体积
  8. Ubuntu下安装Flask虚拟环境及使用
  9. 博途v14 加入C语言的方法,如何利用博途V14新建S7-1200项目?
  10. LiteIDE主题定制教程
  11. 迅雷出现应版权方要求,无法下载的解决办法
  12. 怎样回答面试题更好?以及注意事项
  13. Windows11安卓子系统安装软件方法
  14. 谷歌浏览器开发者工具鼠标箭头变成小圆点了
  15. Fw:[一恒茶社] 作为大学教师,我 感到羞耻??教师节有感及其他[转贴]
  16. win10计算机本地连接属性在哪里,Win10系统怎么打开本地连接属性
  17. 阿里巴巴与微软、苹果、亚马逊的实力对比
  18. C_TFIN52_67 - SAP PA认证考试真题 Financial Accounting with SAP ERP
  19. 3D Human Pose Estimation with 2D Marginal Heatmaps
  20. 遨博协作机器人ROS开发 - 机器人手眼标定原理

热门文章

  1. oracle报错ora-01033解决办法
  2. RGB565 转 RGB
  3. Drozer的基本使用
  4. syncnavigator关于win10、win8系统无法注册机进行激活的问题
  5. oracle的join 优化,oracle索引优化之join部分
  6. 软件测试工具介绍 (静态测试工具和动态测试工具)
  7. Shader编程教程_Shader新手入门视频教程_Shader编程从入门到精通
  8. python入门经典书书籍-新手Python入门经典书籍推荐
  9. linux下gflags2.2.2的正确安装方法
  10. js递归遍历json对象,js循环遍历json数组