ABC068D
D - Decrease (Contestant ver.)
長さの数列において、最大値の値を減らすという操作を回行うことにより、最大値がになるような数列を求めよという問題です。
に厳しめの制約がある為、の場合を考えます。
私は、が変化した場合に何を変化させれば良いのかをから順に考えました。
特に記述がない限り、とします。
の場合、です。
最初から最大値がである必要があります。
の場合、、または、かつです。
の場合は、によって最大値がになります。
かつの場合は、によって最大値がになります。
の制約を考えると、後者の方が良さそうです。
同じように考えると、の場合、であれば良いことがわかります。
つまりは、49から0までの数列を作っておき、左側からKの値だけインクリメントして行けば良さそうです。
では、一番右まで行ってしまった場合、つまりの場合はどうすれば良いでしょうか。
結論としては、の時点で、となっているため、をインクリメントすれば良いです。
つまりは、一番左に戻れば良いという事ですね。
ただ、1ずつインクリメントするのは明らかにTLEするので、実装では各において、を足した後、だけ左側からインクリメントしています。
/* typedef long long ll; */ ll k; cin >> k; int n = 50; vector<ll> a(n); for (int i = 0; i < n; i++) a[i] = n - 1 - i + k / n; for (int i = 0; i < k % n; i++) a[i]++; cout << n << endl << a.front(); for (int i = 1; i < n; i++) cout << " " << a[i]; cout << endl;
説明難しい。