0w1

HE April Circuits 3A - Bear and Vectors ( Math )

https://www.hackerearth.com/april-circuits/algorithm/circ-bear-and-vectors/
Two vectors v1( a1, b1 ), v2( a2, b2 ) are perpendicular to each other iff ( v1 dot v2 ) = a1 * a2 + b1 * b2 = 0.
And since ( ka, kb ) = k( a, b ) is parallel to ( a, b ), we will only have to store each vector as its simplest form ( a and b are co-prime ).
Then we can enumerate for each pair of distinct vectors v1, v2, having v1+2( a1 + a2, b1 + b2 ), simplify them until they are co-prime, say ( a', b' ), then we will have to find how many vectors in the input are of the form ( b', -a' ) or ( -b', a' ). These are the only two ways their dot product will be zero.
At last, we will have to subtract away cases where the enumerated v1, v2 is perpendicular to v1 or v2, which is summed in from the previous step. Simply enumerate pairs of distinct vectors v1, v2 again and check whether it is the case.

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e3 + 3;
const int MAXABSXY = 1e9 + 9;
typedef long long ll;
typedef pair< int, int > pii;

int n;
int x[ MAXN ], y[ MAXN ];

void solve(){
    ll ans = 0;
    map< pii, int > mpi;
    for( int i = 0; i < n; ++i ){
        int gcd = __gcd( abs( x[ i ] ), abs( y[ i ] ) );
        ++mpi[ pii( x[ i ] / gcd, y[ i ] / gcd ) ];
    }
    for( int i = 0; i < n; ++i )
        for( int j = i + 1; j < n; ++j ){
            int nx = x[ i ] + x[ j ];
            int ny = y[ i ] + y[ j ];
            if( nx == 0 && ny == 0 ) continue;
            int gcd = __gcd( abs( nx ), abs( ny ) );
            if( mpi.count( pii( -ny / gcd, nx / gcd ) ) )
                ans += mpi[ pii( - ny / gcd, nx / gcd ) ];
            if( mpi.count( pii( ny / gcd, - nx / gcd ) ) )
                ans += mpi[ pii( ny / gcd, - nx / gcd ) ];
        }
    for( int i = 0; i < n; ++i )
        for( int j = 0; j < n; ++j ) if( i != j ){
            int nx = x[ i ] + x[ j ];
            int ny = y[ i ] + y[ j ];
            if( nx == 0 && ny == 0 ) continue;
            if( (ll)nx * x[ i ] + (ll)ny * y[ i ] == 0 )
                --ans;
        }
    printf( "%lld\n", ans * 2 );
}

int main(){
    scanf( "%d", &n );
    for( int i = 0; i < n; ++i )
        scanf( "%d%d", x + i, y + i );
    solve();
    return 0;
}