Large となるための条件
実は、 で Large となります。
解法1
愚直に実装します。オーバーフローに気を付けてください。
から を求めるときの計算量は です。
解法2
全体を通して見ると、わざわざ 進数に変換することが無駄であるように見えます。
の操作以外は全て基数に関する操作なので、数を桁ごとに配列で管理し、基数は別で管理すればよいです。
この解法ではオーバーフロー等を気にする必要はありません。
から を求めるときの計算量は です。
解法2の実装例(C++)
#include <bits/stdc++.h>
using namespace std;
int main()
{
int N;
cin >> N;
vector<int> num(32, 0);
int i = 0;
while (N)
{
num[i++] = N & 1;
N >>= 1;
}
for (int ans = 1; ans <= 1'000'000; ans++)
{
int j = 0;
while (num[j] == 0)
{
j++;
if (j == 32)
{
cout << ans << endl;
return 0;
}
}
num[j]--;
while (j)
num[--j] = ans + 1;
}
cout << "Large" << endl;
}
Bonus: を で割った余りを求めよ。
の長さが有限になることの証明のお気持ち
この証明では順序数 を用います。
未満の順序数 について考えます。(ここで、)
に対し、 を の を全て に置き換えた自然数とします。
(つまり、)
が有限の場合と無限の場合で場合分けすることで、 を導くことができます。
次に、 のとき、つまり が後続順序数であるとき、 に関わらず とします。
ここから、 を得ます。
以上を組み合わせ、以下のように順序数列 を定めます。
- は を満たす順序数のうち、 を満たす唯一の順序数
- について、
すると、 と の間に、 という関係式が成り立ちます。
から、 は狭義単調減少列です。
順序数に無限降下列は存在しないので、 は有限の長さで にたどり着きます。 から、 も有限回で にたどり着くことが分かりました。
ユーザー解説
ユーザー解説を書くユーザー解説はまだありません。