Submission #958250


Source Code Expand

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

public class Main {
  void run() {
    int n = ni();
    ArrayList<ArrayList<ArrayList<Integer>>> list = new ArrayList<>();
    for (int i = 0; i <= 100000; ++i) {
      ArrayList<ArrayList<Integer>> sub = new ArrayList<>();
      for (int j = 0; j < 4; ++j) {
        sub.add(new ArrayList<>());
      }
      list.add(sub);
    }
    int[] rs = new int[n];
    int[] hs = new int[n];
    for (int i = 0; i < n; ++i) {
      int r = ni();
      int h = ni();
      list.get(r).get(h).add(i);
      rs[i] = r;
      hs[i] = h;
    }
    BIT<Integer> bit = new BIT<>(100000, (a, b) -> a + b, () -> 0);
    for (int i = 1; i <= 100000; ++i) {
      int cnt = 0;
      for (int j = 1; j <= 3; ++j) {
        cnt += list.get(i).get(j).size();
      }
      bit.update(i, cnt);
    }

    int[][] janken = {
        {},
        {2, 3},
        {3, 1},
        {1, 2}
    };
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < n; ++i) {
      int r = rs[i];
      int h = hs[i];
      int win = bit.reduce(0, r - 1) + list.get(r).get(janken[h][0]).size();
      int lose = n - bit.reduce(0, r) + list.get(r).get(janken[h][1]).size();
      int draw = list.get(r).get(h).size() - 1;
      sb.append(win + " " + lose + " " + draw + "\n");
    }
    System.out.print(sb.toString());
  }

  Scanner sc = new Scanner(System.in);

  public static void main(String[] args) {
    new Main().run();
  }

  int ni() {
    return Integer.parseInt(sc.next());
  }

  void debug(Object... os) {
    System.err.println(Arrays.deepToString(os));
  }

  class BIT<T> {
    int n;
    ArrayList<T> bit;
    BiFunction<T, T, T> bif;

    /**
     * 1-indexed なBinary Indexed Treeを構築する
     *
     * @param n   容量
     * @param bif 適用させる関数
     * @param sup 初期値
     */
    BIT(int n, BiFunction<T, T, T> bif, Supplier<T> sup) {
      this.n = n;
      bit = new ArrayList<>(n + 1);
      for (int i = 0; i < n + 1; ++i) {
        bit.add(sup.get());
      }
      this.bif = bif;
    }

    /**
     * iの位置の値をvで更新する
     *
     * @param i index
     * @param v 新しい値
     */
    void update(int i, T v) {
      for (int x = i; x <= n; x += x & -x) {
        bit.set(x, bif.apply(bit.get(x), v));
      }
    }

    /**
     * クエリー
     *
     * @param defaultValue 初期値
     * @param i            index
     * @return [1, i]までfを適用した結果
     */
    T reduce(T defaultValue, int i) {
      T ret = defaultValue;
      for (int x = i; x > 0; x -= x & -x) {
        ret = bif.apply(ret, bit.get(x));
      }
      return ret;
    }
  }

  long MOD = 1_000_000_007;

  /**
   * 繰り返し2乗法を用いたべき乗の実装
   *
   * @return a^r (mod 1,000,000,007)
   */
  long pow(long a, long r) {
    long sum = 1;
    while (r > 0) {
      if ((r & 1) == 1) {
        sum *= a;
        sum %= MOD;
      }
      a *= a;
      a %= MOD;
      r >>= 1;
    }
    return sum;
  }

  /**
   * 組み合わせ
   * O(n)
   *
   * @return {}_nC_r
   */
  long C(int n, int r) {
    long sum = 1;
    for (int i = n; 0 < i; --i) {
      sum *= i;
      sum %= MOD;
    }
    long s = 1;
    for (int i = r; 0 < i; --i) {
      s *= i;
      s %= MOD;
    }
    sum *= pow(s, MOD - 2);
    sum %= MOD;

    long t = 1;
    for (int i = n - r; 0 < i; --i) {
      t *= i;
      t %= MOD;
    }
    sum *= pow(t, MOD - 2);
    sum %= MOD;

    return sum;
  }

  double GOLDEN_RATIO = (1.0 + Math.sqrt(5)) / 2.0;

  /**
   * 黄金分割探索
   *
   * @param left  下限
   * @param right 上限
   * @param f     探索する関数
   * @param comp  上に凸な関数を探索するときは、Comparator.comparingDouble(Double::doubleValue)
   *              下に凸な関数を探索するときは、Comparator.comparingDouble(Double::doubleValue).reversed()
   * @return 極値の座標x
   */
  double goldenSectionSearch(double left, double right, Function<Double, Double> f, Comparator<Double> comp) {
    double c1 = divideInternally(left, right, 1, GOLDEN_RATIO);
    double c2 = divideInternally(left, right, GOLDEN_RATIO, 1);
    double d1 = f.apply(c1);
    double d2 = f.apply(c2);
    while (right - left > 1e-9) {
      if (comp.compare(d1, d2) > 0) {
        right = c2;
        c2 = c1;
        d2 = d1;
        c1 = divideInternally(left, right, 1, GOLDEN_RATIO);
        d1 = f.apply(c1);
      } else {
        left = c1;
        c1 = c2;
        d1 = d2;
        c2 = divideInternally(left, right, GOLDEN_RATIO, 1);
        d2 = f.apply(c2);
      }
    }
    return right;
  }

  /**
   * [a,b]をm:nに内分する点を返す
   */
  double divideInternally(double a, double b, double m, double n) {
    return (n * a + m * b) / (m + n);
  }

  /**
   * http://qiita.com/p_shiki37/items/65c18f88f4d24b2c528b
   */
  static class FastScanner {
    private final InputStream in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;

    public FastScanner(InputStream in) {
      this.in = in;
    }

    private boolean hasNextByte() {
      if (ptr < buflen) {
        return true;
      } else {
        ptr = 0;
        try {
          buflen = in.read(buffer);
        } catch (IOException e) {
          e.printStackTrace();
        }
        if (buflen <= 0) {
          return false;
        }
      }
      return true;
    }

    private int readByte() {
      if (hasNextByte()) return buffer[ptr++];
      else return -1;
    }

    private static boolean isPrintableChar(int c) {
      return 33 <= c && c <= 126;
    }

    private void skipUnprintable() {
      while (hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;
    }

    public boolean hasNext() {
      skipUnprintable();
      return hasNextByte();
    }

    public String next() {
      if (!hasNext()) throw new NoSuchElementException();
      StringBuilder sb = new StringBuilder();
      int b = readByte();
      while (isPrintableChar(b)) {
        sb.appendCodePoint(b);
        b = readByte();
      }
      return sb.toString();
    }

    public long nextLong() {
      if (!hasNext()) throw new NoSuchElementException();
      long n = 0;
      boolean minus = false;
      int b = readByte();
      if (b == '-') {
        minus = true;
        b = readByte();
      }
      if (b < '0' || '9' < b) {
        throw new NumberFormatException();
      }
      while (true) {
        if ('0' <= b && b <= '9') {
          n *= 10;
          n += b - '0';
        } else if (b == -1 || !isPrintableChar(b)) {
          return minus ? -n : n;
        } else {
          throw new NumberFormatException();
        }
        b = readByte();
      }
    }
  }
}

Submission Info

Submission Time
Task B - AtCoderでじゃんけんを
User arukuka
Language Java8 (OpenJDK 1.8.0)
Score 100
Code Size 7189 Byte
Status AC
Exec Time 1711 ms
Memory 108500 KB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 100 / 100
Status
AC × 3
AC × 28
Set Name Test Cases
Sample sample_01.txt, sample_02.txt, sample_03.txt
All 01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, 24.txt, 25.txt, 26.txt, 27.txt, 28.txt
Case Name Status Exec Time Memory
01.txt AC 1206 ms 106816 KB
02.txt AC 1711 ms 104944 KB
03.txt AC 1162 ms 94832 KB
04.txt AC 1220 ms 96212 KB
05.txt AC 1092 ms 94604 KB
06.txt AC 1041 ms 94920 KB
07.txt AC 1224 ms 95276 KB
08.txt AC 1150 ms 96412 KB
09.txt AC 1118 ms 94312 KB
10.txt AC 1169 ms 95440 KB
11.txt AC 1155 ms 108500 KB
12.txt AC 1256 ms 107584 KB
13.txt AC 1196 ms 108404 KB
14.txt AC 1213 ms 95384 KB
15.txt AC 1155 ms 95656 KB
16.txt AC 1157 ms 95248 KB
17.txt AC 1230 ms 103688 KB
18.txt AC 1211 ms 104108 KB
19.txt AC 1464 ms 104176 KB
20.txt AC 1177 ms 107996 KB
21.txt AC 1161 ms 102512 KB
22.txt AC 1195 ms 103712 KB
23.txt AC 1223 ms 107760 KB
24.txt AC 1210 ms 108400 KB
25.txt AC 528 ms 62320 KB
26.txt AC 536 ms 62068 KB
27.txt AC 531 ms 62348 KB
28.txt AC 514 ms 62320 KB
sample_01.txt AC 521 ms 62468 KB
sample_02.txt AC 522 ms 62336 KB
sample_03.txt AC 517 ms 62424 KB