AtCoder Beginner Contest 168 E.∙ (Bullet)

AtCoder Beginner Contest 168 E.∙ (Bullet)

题目链接
AtCoder Beginner Contest 168 E.∙ (Bullet)_第1张图片
明显的数论题,我们假设知道某一对 A i , B i A_i,B_i Ai,Bi 的数量 n u m num num,那么他们可组成的符合条件的对数怎么算?
首先在 n u m num num 里面至少要选一对,即从 C n u m 1 + C n u m 2 + ⋯ + C n u m n u m = 2 n u m − 1 C_{num}^1+C_{num}^2+\cdots+C_{num}^{num}=2^{num}-1 Cnum1+Cnum2++Cnumnum=2num1,剩下的数对为 c n t cnt cnt,他们可以任选,所以情况为 2 c n t 2^{cnt} 2cnt,答案就为 a n s = a n s ∗ ( 2 c n t + 2 n u m − 1 ) ans=ans*(2^{cnt}+2^{num}-1) ans=ans(2cnt+2num1)
下面考虑计算和存储 n u m num num c n t cnt cnt :
m a p map map p a i r pair pair 即可,我们把大的数放前面即可~
注意要特判 a = 0 , b = 0 a=0,b=0 a=0,b=0 的情况,AC代码如下:

#include
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll power(ll a,ll b){return b?power(a*a%mod,b/2)*(b%2?a:1)%mod:1;}
main(){
    ll n,a,b,ans=1,MOD=mod-1;
    cin>>n;
    map<pair<ll,ll>,pair<ll,ll>>m;
    for(ll i=0;i<n;i++){
        cin>>a>>b;
        if(!a&&!b) MOD++;
        else{
            ll g=__gcd(a,b);
            a/=g,b/=g;
            if(b<0) a=-a,b=-b;
            if(a<=0) m[{b,-a}].second++;
            else m[{a,b}].first++;
        }
    }
    for(auto u:m) ans=ans*(power(2,u.second.first)+power(2,u.second.second)-1+mod)%mod;
    cout<<(ans+MOD)%mod;
}

你可能感兴趣的:(AtCoder,数论,map)