题目链接
思路:根据几种情况进行分类讨论
1.a=b=0:选了这个就不能选别的了。
2.a=0:这类数不能和 b=0的一起选
3.b=0:这类数不能和 a=0的一起选
4.other:
我们称满足x情况的数为第x类数。
具体:先将每个数的a,b取一下gcd化简一下。
然后枚举每个数被选的情况下,[1,i-1]有多少种合法选择使得不与i冲突。
设tot为[1,i-1]中第4类数的合法选择数。
那么如果第i个数属于第2类数,那么选了第i个之后,显然[1,i-1]中的第2类数可以选任意多个,第3类数只能选0个,第4类数选择方案为tot种,即为
t
o
t
∗
2
c
n
t
2
tot*2^{cnt_2}
tot∗2cnt2。
如果属于第3类数,同上。
如果属于第4类数:那么选择第i个数之后,第2,3类数的选择方案就有
2
c
n
t
2
+
2
c
n
t
3
−
1
2^{cnt_2}+2^{cnt_3}-1
2cnt2+2cnt3−1种,理解为选任意多第2类数或任意多第3类数,但不同时选,再乘上tot就是包含这个的合法选择方案了。
最后来说tot是怎么维护的。
观察题目给定式子
A
i
A
j
+
B
i
B
j
=
0
A_iA_j+B_iB_j=0
AiAj+BiBj=0即
A
i
B
i
=
−
B
j
A
j
\frac{A_i}{B_i}=-\frac{B_j}{A_j}
BiAi=−AjBj。我们称满足这个式子的两个最简分数匹配。
我们用一个map记录[1,i-1]中第i个分数的出现次数和和第i个分数匹配的分数的出现个数。那么之前tot中肯定包含有这组匹配分数的的一些选择方案,把这个去掉之后的tot就是不包含这组匹配分数的方案了,而第i个分数在[1,i-1]中可以随便选,那么总的方案就是
(
2
c
n
t
2
+
2
c
n
t
3
−
1
)
∗
t
o
t
∗
2
c
n
t
i
(2^{cnt_2}+2^{cnt_3}-1)*tot*2^{cnt_i}
(2cnt2+2cnt3−1)∗tot∗2cnti,最后再把第i个分数出现次数更新,再更新tot即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
int n;
struct uzi{
LL a,b;
}p[N];
const LL mod=1e9+7;
map<pair<LL,LL>,int>m;
LL pm(LL x,LL y){
LL z=1;
while(y){
if(y&1)z=z*x%mod;
x=x*x%mod;
y>>=1;
}
return z;
}
LL fac[N];
int main() {
ios::sync_with_stdio(false);
cin>>n;
fac[0]=1;
for(int i=1;i<=n;i++)fac[i]=fac[i-1]*2%mod;
for(int i=1;i<=n;i++){
cin>>p[i].a>>p[i].b;
LL z=__gcd(labs(p[i].a),labs(p[i].b));
if(z)p[i].a/=z;p[i].b/=z;
if(p[i].b<0)p[i].b=-p[i].b,p[i].a=-p[i].a;
}
LL ans=0,tot=1;
int npb=0,npa=0,gc=0,typ=0,dx=0,dy=0;
for(int i=1;i<=n;i++){
if(!p[i].a && !p[i].b) ans++;
else if(!p[i].a){
ans+=fac[npa]*tot%mod;
ans%=mod;
npa++;
}else if(!p[i].b){
ans+=fac[npb]*tot%mod;
ans%=mod;
npb++;
}else{
int x=m[{p[i].a,p[i].b}];
if(p[i].a<0)p[i].a=-p[i].a,p[i].b=-p[i].b;
int y=m[{-p[i].b,p[i].a}];
tot*=pm((fac[x]+fac[y]-1+mod)%mod,mod-2);
tot%=mod;
ans+=tot*fac[y]%mod*((fac[npa]+fac[npb]-1+mod)%mod)%mod;
ans%=mod;
m[{-p[i].b,p[i].a}]++;
tot*=(fac[x]+fac[y+1]-1+mod)%mod;
tot%=mod;
}
}
cout<<ans<<'\n';
return 0;
}