問題にチャレンジして、ユーザー同士で解答を教え合ったり、コードを公開してみよう!
(はじめに)
以降、s 以上 t 以下の整数の集合を [s,t] と表記します。
いままでで、特定の区間に対する計算結果が頂点に入っていることがわかりました。
それらの区間に対する結果を用いて、任意の区間 [L,R] に対する結果を計算していきます。
そのためには、[L,R] を計算結果がSegment Treeに存在する区間に分割する必要があります。
まず始めにSegment Treeで計算されている区間について確認します。
区間 [s,t] の計算結果がSegment Treeに存在するとき次の条件を満たします。詳しくは問題 7 を参照してください。
分割した区間を入れる配列 ans を用意する。
now を L で初期化する。
now が R を越すまで以下を繰り返す。
次の条件を満たす最大の l を見つける。
R ≧ now + 2 ** l - 1 である。 → 範囲外の要素を含まないための条件
now は 2 ** l の倍数である。 → Segment Treeに計算結果が存在するための条件
[now,now + 2 ** l - 1] を ans に加える。
now に 2 ** l を足す。
入力は以下のフォーマットで与えられます。
Q
L_1 R_1
L_2 R_2
...
L_Q R_Q
i 番目のクエリで x_i 個の区間に分割したとするとき、x_1 + x_2 + ... + x_Q + Q 行で出力してください。
それぞれのクエリに対し以下のように出力してください。
すべてのテストケースについて以下の条件を満たします。
5
3 9
4 8
4 7
12 18
5 20
3
3 1
4 4
8 2
2
4 4
8 1
1
4 4
3
12 4
16 2
18 1
5
5 1
6 2
8 8
16 4
20 1