提出 #13668136


ソースコード 拡げる

import * as fs from 'fs';

const readString = (() => {
  const input = fs.readFileSync(0).toString();
  const words = input.split(/[ \n]/);
  let i = 0;
  return () => words[i++] || '';
})();
const readInt = () => parseInt(readString(), 10);
const readBigInt = () => BigInt(readString());

const gcd = (a: bigint, b: bigint) => {
  const _gcd = (a: bigint, b: bigint): bigint => {
    const q = a % b;
    return q === 0n ? b : _gcd(b, q);
  };
  return a > b ? _gcd(a, b) : _gcd(b, a);
};

const MOD = 1000000007;
const MOD_BIGINT = BigInt(MOD);
class ModBigInt {
  constructor(public v: bigint) { }

  static of(n: number | bigint) {
    return new ModBigInt(ModBigInt.toBigInt(n));
  }

  static toBigInt(other: number | bigint | ModBigInt) {
    if (typeof other === 'bigint') return other;
    if (typeof other === 'number') return BigInt(other);
    return other.v;
  }

  clone = () => new ModBigInt(this.v);
  plus = (other: number | bigint | ModBigInt) => {
    this.v = (this.v + ModBigInt.toBigInt(other)) % MOD_BIGINT;
    return this;
  }
  minus = (other: number | bigint | ModBigInt) => {
    this.v = (this.v + MOD_BIGINT - ModBigInt.toBigInt(other)) % MOD_BIGINT;
    return this;
  }
  multiply = (other: number | bigint | ModBigInt) => {
    this.v = (this.v * ModBigInt.toBigInt(other)) % MOD_BIGINT;
    return this;
  }
  pow = (other: number) => {
    let v = mod(1);
    for (let i = 0; i < other; i++) v.multiply(this.v);
    return v;
  }
}

const mod = ModBigInt.of;

const abs = (a: bigint) => a > 0n ? a : -a;

(function main() {
  const N = readInt();

  let zero: number = 0;
  const groups: { [k: string]: [number, number] } = {};
  Array.from({ length: N }, () => {
    let A = readBigInt();
    let B = readBigInt();
    if (A === 0n && B === 0n) {
      zero++;
    } else if (A === 0n) {
      groups['0:1'] = groups['0:1'] || [0, 0];
      groups['0:1'][0]++;
    } else if (B === 0n) {
      groups['0:1'] = groups['0:1'] || [0, 0];
      groups['0:1'][1]++;
    } else {
      const n = gcd(abs(A), abs(B));
      A /= n;
      B /= n;
      if (A < 0) {
        A *= -1n;
        B *= -1n;
      }

      if (B > 0) {
        const k = `${A}:${B}`;
        groups[k] = groups[k] || [0, 0];
        groups[k][0]++;
      } else {
        const k = `${-B}:${A}`;
        groups[k] = groups[k] || [0, 0];
        groups[k][1]++;
      }
    }
  });

  let result = mod(1);
  for (const k of Object.keys(groups)) {
    const [xn, yn] = groups[k];

    let tmp = mod(0);
    if (xn) {
      tmp.plus(mod(2).pow(xn).minus(1));
    }

    if (yn) {
      tmp.plus(mod(2).pow(yn).minus(1));
    }

    tmp.plus(1);

    result.multiply(tmp);
  }

  result.plus(zero).minus(1);

  console.log(result.v.toString());
})();

提出情報

提出日時
問題 E - ∙ (Bullet)
ユーザ murooka
言語 TypeScript (3.8)
得点 500
コード長 2869 Byte
結果 AC
実行時間 1533 ms
メモリ 151320 KiB

ジャッジ結果

セット名 Sample Subtask1
得点 / 配点 0 / 0 500 / 500
結果
AC × 2
AC × 23
セット名 テストケース
Sample sample_01.txt, sample_02.txt
Subtask1 sample_01.txt, sample_02.txt, sub1_01.txt, sub1_02.txt, sub1_03.txt, sub1_04.txt, sub1_05.txt, sub1_06.txt, sub1_07.txt, sub1_08.txt, sub1_09.txt, sub1_10.txt, sub1_11.txt, sub1_12.txt, sub1_13.txt, sub1_14.txt, sub1_15.txt, sub1_16.txt, sub1_17.txt, sub1_18.txt, sub1_19.txt, sub1_20.txt, sub1_21.txt
ケース名 結果 実行時間 メモリ
sample_01.txt AC 40 ms 29520 KiB
sample_02.txt AC 45 ms 29652 KiB
sub1_01.txt AC 1533 ms 151320 KiB
sub1_02.txt AC 44 ms 29496 KiB
sub1_03.txt AC 41 ms 29536 KiB
sub1_04.txt AC 44 ms 29532 KiB
sub1_05.txt AC 44 ms 29632 KiB
sub1_06.txt AC 45 ms 29540 KiB
sub1_07.txt AC 45 ms 29536 KiB
sub1_08.txt AC 44 ms 29512 KiB
sub1_09.txt AC 45 ms 29488 KiB
sub1_10.txt AC 44 ms 29588 KiB
sub1_11.txt AC 269 ms 61868 KiB
sub1_12.txt AC 521 ms 96492 KiB
sub1_13.txt AC 757 ms 113144 KiB
sub1_14.txt AC 465 ms 96232 KiB
sub1_15.txt AC 117 ms 46596 KiB
sub1_16.txt AC 477 ms 93460 KiB
sub1_17.txt AC 309 ms 68028 KiB
sub1_18.txt AC 377 ms 108036 KiB
sub1_19.txt AC 217 ms 62700 KiB
sub1_20.txt AC 605 ms 107076 KiB
sub1_21.txt AC 129 ms 55824 KiB