#include <cstdio>
#include <cstdint>
#include <vector>
uint64_t query(int l, int r);
uint32_t get(int x);
#define ll uint64_t
const int maxn = 1e6 + 10;
struct Node {
int id, nxt, fnt;
} nd[maxn];
Node *tail;
Node* mv(int val) {
if (!val) return tail;
int id = tail -> nxt;
for (int i = 1; i < val; i++) {
id = nd[id].nxt;
}
return &nd[id];
}
std::pair<int, int> findpos(int n) {
for (int i = 1; i <= n; i++) {
nd[i].id = i;
nd[i].nxt = i + 1;
nd[i].fnt = i - 1;
}
nd[n].nxt = 1;
nd[1].fnt = n;
tail = &nd[n];
int len = n;
while (len > 2) {
int midl = len / 3 + 1, midr = len / 3 * 2;
Node *hd = mv(1), *mvpl = mv(midl), *mvpr = mv(midr), *tl = mv(0);
ll lq = query(hd -> id, mvpr -> id) - query(hd -> id, mvpl -> id - 1),
rq = query(mvpl -> id, tl -> id) - query(mvpr -> id + 1, tl -> id);
if (lq == rq) {
nd[mvpl -> fnt].nxt = mvpr -> nxt;
nd[mvpr -> nxt].fnt = mvpl -> fnt;
} else if (lq > rq) {
mvpl -> fnt = nd[tl -> fnt].nxt;
tl -> nxt = nd[mvpl -> nxt].fnt;
} else {
mvpr -> nxt = nd[hd -> nxt].fnt;
hd -> fnt = nd[mvpr -> fnt].nxt;
tail = mvpr;
}
len = 1;
int p = nd[tail -> nxt].nxt;
while (p != tail -> nxt) {
p = nd[p].nxt;
len++;
}
}
if (len == 1) {
return std::make_pair(tail -> id, get(tail -> id));
} else {
int id1 = tail -> id, id2 = nd[tail -> nxt].id;
uint32_t val1 = get(id1), val2 = get(id2);
if (val1 < val2) {
return std::make_pair(id1, val1);
} else {
return std::make_pair(id2, val2);
}
}
}
std::vector<uint32_t> recover(int n) {
std::vector<uint32_t> ans(n);
auto pos = findpos(n);
ans[pos.first - 1] = pos.second;
ll lastsum = 0;
for (int i = pos.first - 1; i >= 1; i--) {
ll val = query(i, pos.first);
ans[i - 1] = val - lastsum;
lastsum = val;
}
lastsum = 0;
for (int i = pos.first + 1; i <= n; i++) {
ll val = query(pos.first, i);
ans[i - 1] = val - lastsum;
lastsum = val;
}
return ans;
}