結果

問題 No.603 hel__world (2)
ユーザー 👑 hos.lyrichos.lyric
提出日時 2019-06-11 05:50:58
言語 D
(dmd 2.105.2)
結果
WA  
実行時間 -
コード長 4,254 bytes
コンパイル時間 775 ms
コンパイル使用メモリ 113,160 KB
実行使用メモリ 45,608 KB
最終ジャッジ日時 2023-09-04 01:39:02
合計ジャッジ時間 11,203 ms
ジャッジサーバーID
(参考情報)
judge15 / judge11
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 31 ms
29,044 KB
testcase_01 AC 32 ms
29,536 KB
testcase_02 AC 31 ms
28,716 KB
testcase_03 AC 31 ms
28,740 KB
testcase_04 AC 30 ms
29,540 KB
testcase_05 AC 30 ms
29,012 KB
testcase_06 AC 30 ms
28,444 KB
testcase_07 AC 30 ms
29,452 KB
testcase_08 AC 31 ms
28,704 KB
testcase_09 AC 31 ms
28,728 KB
testcase_10 AC 30 ms
28,736 KB
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 AC 32 ms
29,440 KB
testcase_20 AC 51 ms
30,336 KB
testcase_21 AC 51 ms
29,684 KB
testcase_22 AC 31 ms
29,708 KB
testcase_23 AC 31 ms
28,224 KB
testcase_24 AC 31 ms
28,108 KB
testcase_25 WA -
testcase_26 WA -
testcase_27 WA -
testcase_28 WA -
testcase_29 AC 47 ms
29,316 KB
testcase_30 AC 38 ms
30,040 KB
testcase_31 AC 30 ms
29,016 KB
testcase_32 AC 46 ms
30,432 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import std.conv, std.functional, std.range, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.complex, std.container, std.math, std.numeric, std.regex, std.typecons;
import core.bitop;

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }

bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } }
bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } }

int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; }
int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); }
int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); }


enum MO = 10L^^6 + 3;
enum LIM = cast(int)(MO);

long[] inv, fac, invFac;
void prepare() {
  inv = new long[LIM];
  fac = new long[LIM];
  invFac = new long[LIM];
  inv[1] = 1;
  foreach (i; 2 .. LIM) {
    inv[i] = MO - ((MO / i) * inv[cast(size_t)(MO % i)]) % MO;
  }
  fac[0] = invFac[0] = 1;
  foreach (i; 1 .. LIM) {
    fac[i] = (fac[i - 1] * i) % MO;
    invFac[i] = (invFac[i - 1] * inv[i]) % MO;
  }
}
long binom(long n, long k) {
  if (0 <= k && k <= n) {
    long ret = 1;
    for (; k > 0; n /= MO, k /= MO) {
      const nn = n % MO, kk = k % MO;
      if (kk > nn) {
        return 0;
      }
      ret = (ret * fac[cast(size_t)(nn)]) % MO;
      ret = (ret * invFac[cast(size_t)(kk)]) % MO;
      ret = (ret * invFac[cast(size_t)(nn - kk)]) % MO;
    }
    return ret;
  } else {
    return 0;
  }
}

enum M = 26;
enum LIM_P = 60, LIM_Q = 40;

long[] S;
string T;

void main() {
  prepare();
  
  try {
    for (; ; ) {
      S = new long[M];
      foreach (i; 0 .. M) {
        S[i] = readLong();
      }
      T = readToken();
      
      auto lss = new long[][M];
      foreach (t; T.group) {
        lss[t[0] - 'a'] ~= t[1];
      }
      long ans = 1;
      foreach (i; 0 .. M) {
        const ls = lss[i];
        const len = cast(int)(ls.length);
        if (len > 0) {
          const s = S[i] - ls.sum;
          if (s < 0) {
            ans = 0;
            break;
          }
          debug {
            writeln(cast(char)('a' + i), ": s = ", s, ", ls = ", ls);
          }
          /*
            s = #{x | x > 0, (l + x) / x >= r}
          */
          long lo = 0, hi = 1L << LIM_P;
          for (; lo + 1 < hi; ) {
            const mid = (lo + hi) / 2;
            long cnt;
            foreach (l; ls) {
              // l / x >= mid / 2^LIM_Q
              cnt += (l << LIM_Q) / mid;
              chmin(cnt, s + 1);
            }
            (cnt <= s) ? (hi = mid) : (lo = mid);
          }
          auto xs = ls.map!(l => (l << LIM_Q) / hi);
          long lot = s - xs.sum;
          assert(lot >= 0);
          int jm = 0;
          foreach (j; 0 .. len) {
            // ls[jm] / xs[jm] < ls[j] / xs[j]
            // xs[jm] / ls[jm] > xs[j] / ls[j]
            const qm = xs[jm] / ls[jm], rm = xs[jm] % ls[jm];
            const q = xs[j] / ls[j], r = xs[j] % ls[j];
            if (qm > q || qm == q && rm * ls[j] > r * ls[jm]) {
              jm = j;
            }
          }
          auto add = new bool[len];
          foreach (j; 0 .. len) {
            const qm = xs[jm] / ls[jm], rm = xs[jm] % ls[jm];
            const q = xs[j] / ls[j], r = xs[j] % ls[j];
            if (qm == q && rm * ls[j] == r * ls[jm]) {
              if (lot > 0) {
                --lot;
                add[j] = true;
              }
            }
          }
          debug {
            writeln("  xs = ", xs);
            writeln("  add = ", add);
          }
          foreach (j; 0 .. len) {
            ans *= binom(ls[j] + xs[j] + (add[j] ? 1 : 0), ls[j]);
            ans %= MO;
          }
        }
      }
      writeln(ans);
    }
  } catch (EOFException e) {
  }
}
0