#0010.「AtCoder」ABC168E ∙ (Bullet)
题目大意:
n个沙雕鱼(沙丁鱼),每个鱼有一个A,B,若两值鱼i,j满足Ai*Aj+Bi*Bj=0,则他们不能放在一起。问可以有几种选鱼的方法(不可以不选)。对1e9+7取模
n<=2e5, −1e18≤Ai,Bi≤1e18
题目解法:
虽然这道题不难但个人认为解法挺有趣的哈哈哈而且我WA了4次才过
将式子变形:

至此我们发现我们只关心Ai,Bi的差而不关心其具体值。所以我们也不关心A B的符号只关心他们是同号还是异号。
我们想到也许可以通过某种方法把会冲突的鱼放在一起。如果我们要从这堆鱼中选的话我们要么选同号的那些要么选异号的那些。
所以我们的处理方式是这样的。对于每个A,B,我们除掉它们的GCD。如果是异号就交换A,B。然后把A,B全搞成正数。记录下它们原来是同号的还是异号的。这样的处理后我们可以使本来两个冲突的鱼获得同样的A,B。
例如,(1,2) (-8,4)是冲突的。(-8,4)->(-2,1)->(1,-2)->(1,2)。
开一个map< pair <long long, long long>, pair <int, int> >, map[{a,b}].first是处理后A=a,B=b且处理前两者同号的鱼的数量,second是处理后A=a,B=b且处理前两者异号的鱼的数量。
接着我们只需要遍历一遍map,对于每个(a,b)我们有取同号,取异号,不取三种可能,直接用2的次方算就行啦。
注意最后减1因为不可以不选
以及以及不要忘了0的特判。对于(0,0)显然和任何其他鱼都是出不来的。所以我们直接用cnt数有多少个(0,0)最后再加上。A=0的鱼会和B=0的鱼不和反之亦然,所以我们单独存他们。

浙公网安备 33010602011771号