import random
import sys
sys.setrecursionlimit(20000)
nodes = 0
depth = 0
def is_diff_sorted(qa):
diffs = [qa[i] - qa[i+1] for i in range(len(qa)-1)]
for i in range(len(diffs)-1):
if diffs[i] > diffs[i+1]:
return False
return True
def is_concave_end(a, x):
return a[-2] - a[-1] <= a[-1] - x
def append_element(sa, halves, labels, which, x):
labels.append(which)
halves[which].append(x)
if len(labels) == len(sa) or split_to_halves(sa, halves, labels):
return True
if which == 1 or not is_concave_end(halves[1], halves[0][-1]):
halves[which].pop()
labels.pop()
return False
labels[-1] = 1
halves[1].append(halves[0][-1])
halves[0].pop()
if split_to_halves(sa, halves, labels):
return True
halves[1].pop()
labels.pop()
def split_to_halves(sa, halves, labels):
global nodes, depth
nodes += 1
depth = max(depth, len(labels))
x = sa[len(labels)]
if len(halves[0]) < 2 or is_concave_end(halves[0], x):
return append_element(sa, halves, labels, 0, x)
if is_concave_end(halves[1], x):
return append_element(sa, halves, labels, 1, x)
def make_concave(a):
sa = sorted(a, reverse = True)
halves = [[sa[0]], [sa[0], sa[1]]]
labels = [0, 1]
if split_to_halves(sa, halves, labels):
return list(reversed(halves[1][1:])) + halves[0]
#a = [10, 2, 7, 4]
h = [[], []]
v = [0, 0]
d = [0, 0]
for i in range(5000):
for w in range(2):
if v[w] <= v[1-w]:
r = 5
else:
r = 10 + (v[w] - v[1-w]) * 2
d[w] = random.randint(d[w], d[w] + r)
v[w] -= d[w]
h[w].append(v[w])
a = h[0] + h[1]
print is_diff_sorted(make_concave(a))
#print make_concave(a)
print "depth", depth, "nodes", nodes
aW1wb3J0IHJhbmRvbQppbXBvcnQgc3lzCnN5cy5zZXRyZWN1cnNpb25saW1pdCgyMDAwMCkKbm9kZXMgPSAwCmRlcHRoID0gMAoKZGVmIGlzX2RpZmZfc29ydGVkKHFhKToKICBkaWZmcyA9IFtxYVtpXSAtIHFhW2krMV0gZm9yIGkgaW4gcmFuZ2UobGVuKHFhKS0xKV0KICBmb3IgaSBpbiByYW5nZShsZW4oZGlmZnMpLTEpOgogICAgaWYgZGlmZnNbaV0gPiBkaWZmc1tpKzFdOgogICAgICByZXR1cm4gRmFsc2UKICByZXR1cm4gVHJ1ZQoKZGVmIGlzX2NvbmNhdmVfZW5kKGEsIHgpOgogIHJldHVybiBhWy0yXSAtIGFbLTFdIDw9IGFbLTFdIC0geAoKZGVmIGFwcGVuZF9lbGVtZW50KHNhLCBoYWx2ZXMsIGxhYmVscywgd2hpY2gsIHgpOgogIGxhYmVscy5hcHBlbmQod2hpY2gpCiAgaGFsdmVzW3doaWNoXS5hcHBlbmQoeCkKICBpZiBsZW4obGFiZWxzKSA9PSBsZW4oc2EpIG9yIHNwbGl0X3RvX2hhbHZlcyhzYSwgaGFsdmVzLCBsYWJlbHMpOgogICAgcmV0dXJuIFRydWUKICBpZiB3aGljaCA9PSAxIG9yIG5vdCBpc19jb25jYXZlX2VuZChoYWx2ZXNbMV0sIGhhbHZlc1swXVstMV0pOgogICAgaGFsdmVzW3doaWNoXS5wb3AoKQogICAgbGFiZWxzLnBvcCgpCiAgICByZXR1cm4gRmFsc2UKICBsYWJlbHNbLTFdID0gMQogIGhhbHZlc1sxXS5hcHBlbmQoaGFsdmVzWzBdWy0xXSkKICBoYWx2ZXNbMF0ucG9wKCkKICBpZiBzcGxpdF90b19oYWx2ZXMoc2EsIGhhbHZlcywgbGFiZWxzKToKICAgIHJldHVybiBUcnVlCiAgaGFsdmVzWzFdLnBvcCgpCiAgbGFiZWxzLnBvcCgpCgpkZWYgc3BsaXRfdG9faGFsdmVzKHNhLCBoYWx2ZXMsIGxhYmVscyk6CiAgZ2xvYmFsIG5vZGVzLCBkZXB0aAogIG5vZGVzICs9IDEKICBkZXB0aCA9IG1heChkZXB0aCwgbGVuKGxhYmVscykpCgogIHggPSBzYVtsZW4obGFiZWxzKV0KICBpZiBsZW4oaGFsdmVzWzBdKSA8IDIgb3IgaXNfY29uY2F2ZV9lbmQoaGFsdmVzWzBdLCB4KToKICAgIHJldHVybiBhcHBlbmRfZWxlbWVudChzYSwgaGFsdmVzLCBsYWJlbHMsIDAsIHgpCiAgaWYgaXNfY29uY2F2ZV9lbmQoaGFsdmVzWzFdLCB4KToKICAgIHJldHVybiBhcHBlbmRfZWxlbWVudChzYSwgaGFsdmVzLCBsYWJlbHMsIDEsIHgpCgpkZWYgbWFrZV9jb25jYXZlKGEpOgogIHNhID0gc29ydGVkKGEsIHJldmVyc2UgPSBUcnVlKQogIGhhbHZlcyA9IFtbc2FbMF1dLCBbc2FbMF0sIHNhWzFdXV0KICBsYWJlbHMgPSBbMCwgMV0KICBpZiBzcGxpdF90b19oYWx2ZXMoc2EsIGhhbHZlcywgbGFiZWxzKToKICAgIHJldHVybiBsaXN0KHJldmVyc2VkKGhhbHZlc1sxXVsxOl0pKSArIGhhbHZlc1swXQoKI2EgPSBbMTAsIDIsIDcsIDRdCgpoID0gW1tdLCBbXV0KdiA9IFswLCAwXQpkID0gWzAsIDBdCmZvciBpIGluIHJhbmdlKDUwMDApOgogIGZvciB3IGluIHJhbmdlKDIpOgogICAgaWYgdlt3XSA8PSB2WzEtd106CiAgICAgIHIgPSA1CiAgICBlbHNlOgogICAgICByID0gMTAgKyAodlt3XSAtIHZbMS13XSkgKiAyCgogICAgZFt3XSA9IHJhbmRvbS5yYW5kaW50KGRbd10sIGRbd10gKyByKQogICAgdlt3XSAtPSBkW3ddCiAgICBoW3ddLmFwcGVuZCh2W3ddKQphID0gaFswXSArIGhbMV0KCnByaW50IGlzX2RpZmZfc29ydGVkKG1ha2VfY29uY2F2ZShhKSkKI3ByaW50IG1ha2VfY29uY2F2ZShhKQpwcmludCAiZGVwdGgiLCBkZXB0aCwgIm5vZGVzIiwgbm9kZXM=