#include<bits/stdc++.h> usingnamespace std; constint mod = 32768; constint N = 32769; int n; intlowbit(int x){ return x & -x; } int level[N]; int f[N];
intmain(){ #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif scanf("%d", &n); memset(f, -1, sizeof f); for(int i = 0; i < N; ++i) { for(int j = 0; j < 16; ++j) { if((1 << j) & i) { level[i] = j + 1; break; } } } f[0] = 0; while(n--) { int a; scanf("%d", &a); int t = a; if(f[a] != -1) { printf("%d ", f[a]); continue; } int res = 17; for(int k = 0; k <= 16; a += lowbit(a)) { res = min(res, k + 16 - level[lowbit(a)]); k += lowbit(a); } f[t] = res; printf("%d ", res); } return0; }
funmain() { val n = readLine()!!.toInt() val a = readLine()!!.split(' ').map { it.toInt() }.toIntArray()
for (v in a) { var ans = 20 for (cntAdd in0..15) { for (cntMul in0..15) { if (((v + cntAdd) shl cntMul) % 32768 == 0) ans = minOf(ans, cntAdd + cntMul) } } print("$ans ") } }
Let’s solve the problem greedily. But not from the beginning, because if we solve it from the beginning, we can’t be sure what option is more optimal for the next elements (e.g. for the second element it is not clear if we need to add $2$ to it starting our segment from the first position or add $1$ to it starting our segment from the second position). So, let’s solve the problem from right to left, then anything becomes clearer.
Actually, let’s operate with the array $b$ and decrease its elements instead of using some other array. Let’s carry some variables: $sum$, $cnt$ and the array $closed$ of length $n$ (along with the answer). The variable $sum$ means the value we need to subtract from the current element from currently existing progressions, $cnt$ is the number of currently existing progressions, and $closed_i$ means the number of progressions that will end at the position $i+1$ (i.e. will not add anything from the position $i$ and further to the left).
When we consider the element $i$, firstly let’s fix $sum$ (decrease it by $cnt$). Then, let’s fix $cnt$ (decrease it by $closed_i$). Then, let’s decrease $b_i$ by $sum$, and if it becomes less than or equal to zero, just proceed. Otherwise, the number by which we can decrease the $i$-th element with one progression, equals to $el=\min(k,i+1)$ (zero-indexed). Then the number of progressions we need to satisfy this element is $need=⌈b_i/el⌉$. Let’s add this number to the answer, increase $sum$ by $el⋅need$, increase $cnt$ by $need$, and if $i−el≥0$ then we need to end these progressions somewhere, so let’s add $need$ to $closed_{i−el}$.
int n, k; scanf("%d %d", &n, &k); vector<longlong> b(n); for (auto &it : b) { scanf("%lld", &it); } vector<longlong> closed(n); longlong sum = 0, cnt = 0, ans = 0; for (int i = n - 1; i >= 0; --i) { sum -= cnt; cnt -= closed[i]; b[i] -= sum; if (b[i] <= 0) { continue; } int el = min(i + 1, k); longlong need = (b[i] + el - 1) / el; sum += need * el; cnt += need; ans += need; if (i - el >= 0) { closed[i - el] += need; } } printf("%lld\n", ans); return0; }