AtCoder Regular Contest 129

コンテスト前のレート:2018
レート通りのパフォーマンスが得られる順位:277位(1200点、76分09秒)

A - Smaller XOR

問題

思考過程
  1. とりあえずこういう形の問題は、f(X)x \le Xの場合の答えとして、f(R) - f(L-1)で求めたい。
     
  2. (x \oplus N) \lt Nという条件については、適当にN = 0010110などとしてみてxとしてどのような値が可能かを考える。(一旦x \le Xの条件は考えない)
  3. 前の桁から調べていき、まず初めの2桁の部分についてx側が1だと(x \oplus N)の当該桁も1となり、条件を満たさない。
  4. x3桁目を1とする場合、(x \oplus N)の当該桁は0となり、以降の4桁は2^4通り任意に選べる。
  5. x3桁目を0とする場合は、上3桁がN = (x \oplus N)となるので、上3桁をないものとして以降の桁で同様の数え上げを繰り返せる。
     
  6. ここにx \le Xの条件を取り込むことを考える。
  7. 上記4.の3桁目の処理で数え上げている値は、00100000011111の範囲の値全てとなるので、この範囲かつX以下である値の数を加算するように変更する。
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] sa = br.readLine().split(" ");
        long n = Long.parseLong(sa[0]);
        long l = Long.parseLong(sa[1]) - 1;
        long r = Long.parseLong(sa[2]);
        br.close();

        System.out.println(calc(r, n) - calc(l, n));
    }

    static long calc(long x, long m) {
        long ret = 0;
        char[] s = Long.toBinaryString(m).toCharArray();
        int n = s.length;
        for (int i = 0; i < n; i++) {
            if (s[i] == '1') {
                int a = n - i;
                int a1 = n - i - 1;
                long r = (1L << a) - 1;
                long l = (1L << a1) - 1;
                ret += Math.max(Math.min(r, x) - l, 0);
            }
        }
        return ret;
    }
}

ここまで12分26秒+0ペナ。291位。


B - Range Point Distance

問題
3分くらいで解いている人が何人もいたので、単純に考えることにした。

思考過程
  1. 感覚的には、x区間k個ある内の真ん中辺りにしたい。
  2. そうすると、distmax(x - R_{min}, L_{max} - x)になる。
  3. 結局R_{min}L_{max}の間の中央にxを指定することになるので、累積max、累積minを管理しながら\lceil \frac{L_{max} - R_{min}}{2} \rceilを求めればよい。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        int[] l = new int[n];
        int[] r = new int[n];
        for (int i = 0; i < n; i++) {
            String[] sa = br.readLine().split(" ");
            l[i] = Integer.parseInt(sa[0]);
            r[i] = Integer.parseInt(sa[1]);
        }
        br.close();

        int lmax = 0;
        int rmin = 1000000000;
        PrintWriter pw = new PrintWriter(System.out);
        for (int i = 0; i < n; i++) {
            lmax = Math.max(lmax, l[i]);
            rmin = Math.min(rmin, r[i]);
            pw.println(Math.max((lmax - rmin + 1) / 2, 0));
        }
        pw.flush();
    }
}

ここまで18分56秒+0ペナ。158位。



残り時間はCに1時間、Dに40分ほど使った。
Cは例2を見て777\cdots x777\cdots x777\cdotsという形にしたくなるが、干渉しないようにxを定めることができなかった。

1時間経過する頃にはCを通しても旨味はなくなってきていたので、Dを通すことで逆転を狙おうとするが、何もわからず。



終結果:ABの2完700点、18分56秒、528位、パフォーマンス1590
レート変動:2018→1982(-36)


来週のABC229がついにABC192以来のRatedABCとなってしまった。
(黄色になって以来これまで二度青に落ちているが、二度ともARCorAGCが連続しているところで、間にRatedABCが入る前に黄色復帰していた)

これで果たしてどこまで落ちていくか・・・。