Problem:
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});

A: トーナメント

問題

AOR イカちゃんとあなたは、トーナメント形式の卓球大会シングルスの部に偵察に来た。
全ての試合を録画したい AOR イカちゃんのために、あなたはこの大会で行われる試合数を求めてあげることにした。

この大会には $N$ 人の選手が参加しており、それぞれ $0, \dots , N - 1$ の背番号を持っている。
そのうち、 $M$ 人の選手が棄権し、試合には出場しなかった。

この大会の試合数は、以下のルールに基いて決定される。

シード選手は存在せず、任意の出場者が優勝するために必要な勝利回数は一定である。

対戦相手が不在の場合は試合を行わず、出場した選手が勝利する。試合数にはカウントされない。

優勝者が決まった段階で大会は終了する。

一度試合に負けた人が再び試合をすることはない。つまり敗者復活戦や 3 位決定戦などは行わない。

なお、卓球台が 1 台しか無いため異なる試合が同時に行われることはなく、また各試合では必ず勝者が決まる (引き分けとなることはない)。

なお、トーナメントの定義は次のとおりである。
トーナメントは高さ $L = \log_2 N$ の完全二分木で表され、葉にあたる各頂点には参加者の背番号が書き込まれている。
根の深さを 0 とすると、 $i$ 回戦 ($1 \le i \le L$) では、
深さ $L - i$ の各頂点の子に書かれた番号の選手同士が試合を行い、その勝者の背番号をその頂点に書き込む。

制約

$2 \le N \le 2^8$

$0 \le M \le N - 1$

$0 \le a_i \le N - 1 \ (0 \le i \le M - 1)$

$N$ は 2 の累乗である。

$a_i \ (0 \le i \le M - 1)$ は相異なる

入力形式

入力は以下の形式で与えられる。

$N \ M$

$a_1$

$\vdots$

$a_M$

1 行目には、参加者を表す整数 $N$ 、参加者のうち棄権した者の人数を表す整数 $M$ が与えられる。

続く $M$ 行には、棄権して出場しなかった選手の番号を表す整数 $a_i$ が与えられる。

出力

この大会が終了するまでに行われる試合数を 1 行で出力せよ。また、末尾に改行も出力せよ。

サンプル

サンプル入力 1

2 0

サンプル出力 1

1

最初の試合で優勝者が決まる。

サンプル入力 2

4 2
2
3

サンプル出力 2

1

Solution in JAVA (judge verdict: Wrong Answer)


import java.io.*;
import java.util.*;

/**
 * AIZU ONLINE JUDGE
 * 2805 Tournament
 *    2018/02/11
 */
public class Main {


	// メイン return falseでおしまい
	boolean main() throws IOException {

		int[] ir = readIntArray();
		int N = ir[0];
		int M = ir[1];

		log.printf("N,M = %d, %d\n", N, M);

		int[] a = new int[N];
		for(int i = 0; i < M; i++) {
	        ir = readIntArray();
            a[ir[0]] = 1;
	        log.printf("a = %d\n", ir[0]);
		}
		int cnt = 0;
		for(int n = N; n > 0; n /= 2) {
		    for(int i = 0; i < n; i += 2) {
		        if (a[i] == 0 && a[i + 1] == 0) {
		            cnt++;
		        }
		        int t = 0;
                if (a[i] != 0 && a[i + 1] != 0) {
                    t = 1;
                }
		        a[i / 2] = t;
		    }
		}

		result.printf("%d\n", cnt);

		return true; // 正常終了 次へ
	}



	static long time0;
	private final static boolean DEBUG = false; // release

    PrintStream log;
    PrintStream result;
    BufferedReader systemin;
    PrintStream DEVNULL = new PrintStream(new OutputStream() { public void write(int b) {} } );

    static Main instance = new Main();

    Main() {
        log = DEVNULL;
        systemin = new BufferedReader(new InputStreamReader(System.in)); // コンソールから
        result = System.out;
    }

	public static void main(String[] args) throws IOException {

		int N = Integer.MAX_VALUE;
		//int N = readIntArray()[0];

//		for(int i = 0; i < N; i++) {
			boolean b = instance.main();
//			if (!b)
//				break;
//		}

        instance.systemin.close();
	}


	// 標準入力より1行分の区切り文字区切りでの整数値を読む
	// EOFの場合はnullを返す
	private int[] readIntArray() throws IOException {

		String s = null;
		for(;;) {
			s = systemin.readLine();
//			log.printf("%s\n", s);
			if (s == null)
				return null;
			s = s.trim();
			if (s.length() != 0) // 突然空行を読むことがある。読み飛ばすとうまくいくらしい。。。。
				break;
		}

		String[] sp = s.split("[ ,]"); // 区切り文字はスペースかカンマ
		int[] a = new int[sp.length];
		for(int i = 0; i < sp.length; i++) {
			a[i] = Integer.parseInt(sp[i]);
		}
		return a;
	}

}