Problem:


Score : 1000 points

Problem Statement

There are N oases on a number line. The coordinate of the i-th oases from the left is x_i.

Camel hopes to visit all these oases.
Initially, the volume of the hump on his back is V. When the volume of the hump is v, water of volume at most v can be stored. Water is only supplied at oases. He can get as much water as he can store at a oasis, and the same oasis can be used any number of times.

Camel can travel on the line by either walking or jumping:

Walking over a distance of d costs water of volume d from the hump. A walk that leads to a negative amount of stored water cannot be done.

Let v be the amount of water stored at the moment. When v>0, Camel can jump to any point on the line of his choice. After this move, the volume of the hump becomes v/2 (rounded down to the nearest integer), and the amount of stored water becomes 0.

For each of the oases, determine whether it is possible to start from that oasis and visit all the oases.

Constraints

2 ≤ N,V ≤ 2 × 10^5

-10^9 ≤ x_1 < x_2 < ... < x_N ≤ 10^9

V and x_i are all integers.

Input

Input is given from Standard Input in the following format:

N V
x_1 x_2 ... x_{N}

Output

Print N lines. The i-th line should contain Possible if it is possible to start from the i-th oasis and visit all the oases, and Impossible otherwise.

Sample Input 1

3 2
1 3 6

Sample Output 1

Possible
Possible
Possible

It is possible to start from the first oasis and visit all the oases, as follows:

Walk from the first oasis to the second oasis. The amount of stored water becomes 0.

Get water at the second oasis. The amount of stored water becomes 2.

Jump from the second oasis to the third oasis. The amount of stored water becomes 0, and the volume of the hump becomes 1.

Sample Input 2

7 2
-10 -4 -2 0 2 4 10

Sample Output 2

Impossible
Possible
Possible
Possible
Possible
Possible
Impossible

A oasis may be visited any number of times.

Sample Input 3

16 19
-49 -48 -33 -30 -21 -14 0 15 19 23 44 52 80 81 82 84

Sample Output 3

Possible
Possible
Possible
Possible
Possible
Possible
Possible
Possible
Possible
Possible
Possible
Possible
Impossible
Impossible
Impossible
Impossible



Sample input:
3 2
1 3 6


Sample output:
Possible
Possible
Possible

Submission status: Wrong Answer

Solution code:
import copy
from functools import reduce

def jumps(vol):
	j = 0
	while vol > 0:
		vol = vol // 2
		j += 1
	return j

def visitable(oases, i, vol):
	return visitable_r(oases, i, vol, [False] * len(oases))

def visitable_r(oases, i, vol, visited):
	# visit all visitable by sliding
	visited[i] = True
	# print("i: ", i, " vol: ", vol)
	# print(visited)
	j = i + 1
	while j < len(oases) and (oases[j] - oases[j-1] <= vol):
		visited[j] = True
		j += 1
	j = i - 1
	while j >= 0 and (oases[j+1] - oases[j] <= vol):
		visited[j] = True
		j -= 1
	# print("spread: ", visited)

	if reduce((lambda x, y: x and y), visited):
		return True
	if vol == 0:
		return False

	if not checkMaybeViable(visited, vol):
		return False
	unvisited = 0
	for j in range(len(oases)):
		if not visited[j]:
			unvisited += 1
			if visitable_r(oases, j, vol//2, copy.copy(visited)):
				return True
	return unvisited == 0

def checkMaybeViable(visited, vol):
	jump = jumps(vol)
	isles = 0
	lastNeedToVisit = 0
	for i in range(len(visited)):
		if i == 0 or ((oases[i] - lastNeedToVisit > vol) and (not visited[i])):
			lastNeedToVisit = oases[i]
			isles += 1
			if isles > jump + 1:
				return False
	return True

# [n, vol] = list(map(lambda x: int(x), "16 19".split()))
# oases = list(map(lambda x: int(x), "-49 -48 -33 -30 -21 -14 0 15 19 23 44 52 80 81 82 84".split()))
[n, vol] = list(map(lambda x: int(x), input().split()))
oases = list(map(lambda x: int(x), input().split()))
for i in range(n):
	if visitable(oases, i, vol):
		print("Possible")
	else:
		print("Impossible")

Submission status: Wrong Answer

Solution code:
import copy
from functools import reduce

def jumps(vol):
	j = 0
	while vol > 0:
		vol = vol // 2
		j += 1
	return j

def visitable(oases, i, vol):
	return visitable_r(oases, i, vol, [False] * len(oases))

def visitable_r(oases, i, vol, visited):
	# visit all visitable by sliding
	visited[i] = True
	# print("i: ", i, " vol: ", vol)
	# print(visited)
	j = i + 1
	while j < len(oases) and (oases[j] - oases[j-1] <= vol):
		visited[j] = True
		j += 1
	j = i - 1
	while j >= 0 and (oases[j+1] - oases[j] <= vol):
		visited[j] = True
		j -= 1
	# print("spread: ", visited)

	if reduce((lambda x, y: x and y), visited):
		return True

	if not checkMaybeViable(visited, vol):
		return False
	unvisited = 0
	for j in range(len(oases)):
		if not visited[j]:
			unvisited += 1
			if visitable_r(oases, j, vol//2, copy.copy(visited)):
				return True
	return unvisited == 0

def checkMaybeViable(visited, vol):
	jump = jumps(vol)
	isles = 0
	lastNeedToVisit = 0
	for i in range(len(visited)):
		if i == 0 or ((oases[i] - lastNeedToVisit > vol) and (not visited[i])):
			lastNeedToVisit = oases[i]
			isles += 1
			if isles > jump + 1:
				return False
	return True

[n, vol] = list(map(lambda x: int(x), input().split()))
oases = list(map(lambda x: int(x), input().split()))
for i in range(n):
	if visitable(oases, i, vol):
		print("Possible")
	else:
		print("Impossible")

Submission status: Time Limit Exceeded

Solution code:
n,v=map(int,raw_input().split())
a=map(int,raw_input().split())
m=0
vv=v
while vv>0:
    vv/=2
    m+=1
m+=1
nxl=[[None]*m for _ in xrange(n)]
nxr=[[None]*m for _ in xrange(n)]
for j in xrange(m):
    nxl[n-1][j]=n-1
    nxr[0][j]=0
for j in xrange(m):
    now=0
    pre=0
    while now<n-1:
        while now<n-1:
            nx=now+1
            if a[nx]-a[now]>v/(2**j):break
            now=nx
        for i in xrange(pre,nx):
            nxl[i][j]=now
        pre=nx
        now=nx
for j in xrange(m):
    now=n-1
    pre=n-1
    while now>0:
        while now>0:
            nx=now-1
            if a[now]-a[nx]>v/(2**j):break
            now=nx
        for i in xrange(pre,nx,-1):
            nxr[i][j]=now
        pre=nx
        now=nx
dpl=[0]*(1<<m)
dpr=[n-1]*(1<<m)
for i in xrange(1<<m):
    for j in xrange(m):
        if not (i>>j&1):
            L=nxl[dpl[i]][j]
            R=nxr[dpr[i]][j]
            if L==n-1:L-=1
            if R==0:R+=1
            dpl[i|(1<<j)]=max(dpl[i|(1<<j)],L+1)
            dpr[i|(1<<j)]=min(dpr[i|(1<<j)],R-1)

for i in xrange(n):
    left=nxr[i][0]
    right=nxl[i][0]
    ok=False
    for j in xrange(1<<m):
        if (j&1):continue
        if dpl[j]>=left:
            nokori=((1<<m)-1)^j
            nokori-=1
            if dpr[nokori]<=right:
                ok=True
                break
    print "Possible" if ok else "Impossible"

Submission status: Memory Limit Exceeded

Solution code:
n,v=map(int,raw_input().split())
a=map(int,raw_input().split())
m=0
vv=v
while vv>0:
    vv/=2
    m+=1
m+=1
nxl=[[None]*m for _ in xrange(n)]
nxr=[[None]*m for _ in xrange(n)]
for j in xrange(m):
    nxl[n-1][j]=n-1
    nxr[0][j]=0
for j in xrange(m):
    now=0
    pre=0
    while now<n-1:
        while now<n-1:
            nx=now+1
            if a[nx]-a[now]>v/(2**j):break
            now=nx
        for i in xrange(pre,nx):
            nxl[i][j]=now
        pre=nx
        now=nx
for j in xrange(m):
    now=n-1
    pre=n-1
    while now>0:
        while now>0:
            nx=now-1
            if a[now]-a[nx]>v/(2**j):break
            now=nx
        for i in xrange(pre,nx,-1):
            nxr[i][j]=now
        pre=nx
        now=nx
dpl=[0]*(1<<m)
dpr=[n-1]*(1<<m)
for i in xrange(1<<m):
    for j in xrange(m):
        if not (i>>j&1):
            L=nxl[dpl[i]][j]
            R=nxr[dpr[i]][j]
            if L==n-1:L-=1
            if R==0:R+=1
            dpl[i|(1<<j)]=max(dpl[i|(1<<j)],L+1)
            dpr[i|(1<<j)]=min(dpr[i|(1<<j)],R-1)
f=False
ok=[0]*(n+1)
for i in xrange(1<<m):
    if i&1:i=i^1
    left=dpl[i]
    nokori=((1<<m)-1)^i
    nokori-=1
    right=dpr[nokori]
    if left<right:
        if nxl[left][0]>=right:
            ok[left]+=1
            ok[right+1]-=1
    else:
        f=True
        break
if f:
    for i in xrange(n):
        print "Possible"
else:
    for i in xrange(n):
        ok[i+1]+=ok[i]
    for i in xrange(n):
        print "Possible" if ok[i]>0 else "Impossible"

Submission status: Memory Limit Exceeded

Solution code:
n,v=map(int,raw_input().split())
a=map(int,raw_input().split())
m=0
vv=v
while vv>0:
    vv/=2
    m+=1
m+=1
nxl=[[None]*m for _ in xrange(n)]
nxr=[[None]*m for _ in xrange(n)]
for j in xrange(m):
    nxl[n-1][j]=n-1
    nxr[0][j]=0
for j in xrange(m):
    now=0
    pre=0
    while now<n-1:
        while now<n-1:
            nx=now+1
            if a[nx]-a[now]>v/(2**j):break
            now=nx
        for i in xrange(pre,nx):
            nxl[i][j]=now
        pre=nx
        now=nx
for j in xrange(m):
    now=n-1
    pre=n-1
    while now>0:
        while now>0:
            nx=now-1
            if a[now]-a[nx]>v/(2**j):break
            now=nx
        for i in xrange(pre,nx,-1):
            nxr[i][j]=now
        pre=nx
        now=nx
dpl=[0]*(1<<m)
dpr=[n-1]*(1<<m)
for i in xrange(1<<m):
    for j in xrange(m):
        if not (i>>j&1):
            L=nxl[dpl[i]][j]
            R=nxr[dpr[i]][j]
            if L==n-1:L-=1
            if R==0:R+=1
            dpl[i|(1<<j)]=max(dpl[i|(1<<j)],L+1)
            dpr[i|(1<<j)]=min(dpr[i|(1<<j)],R-1)
f=False
ok=[False]*n
for i in xrange(1<<m):
    if i&1:i=i^1
    left=dpl[i]
    nokori=((1<<m)-1)^i
    nokori-=1
    right=dpr[nokori]
    if left<right:
        if nxl[left][0]>=right:
            for j in xrange(left,right+1):
                ok[j]=True
    else:
        f=True
        break
if f:
    for i in xrange(n):
        print "Possible"
else:
    for i in xrange(n):
        print "Possible" if ok[i] else "Impossible"

Submission status: Runtime Error

Solution code:
n = map(int, raw_input().split())
x = map(int, raw_input().split())
#x.sort(reverse = True)
#print x
for i in range(0, n[0]):
    mem = [0]*n[0]
    v = n[1]
    V = n[1]
    mem[i]=1
    go(mem,v,i,V)
    if chk(mem) == 1:
        print Possible
    else:
        print Impossible
        
def go(mem,v,i,V):
    if (i-1)<0:
        if x[i+1]-x[i]<=v and mem[i+1]==0:
            mem[i+1]=1
            go(mem,V,i+1,V)
        elif V>=1:
            for j in range(0,n[0]):
                if mem[j]==0:
                    go(mem,V/2,j,V/2)
        else:
            return 0
    elif (i+1)==n[0]:
        if x[i]-x[i-1]<=v and mem[i-1]==0:
            mem[i-1]=1
            go(mem,v,i-1,V)
        elif V>=1:
            for j in range(0,n[0]):
                if mem[j]==0:
                    go(mem,V/2,j,V/2)
        else:
            return 0
    else:
        if x[i+1]-x[i]<=v and mem[i+1]==0:
            mem[i+1]=1
            go(mem,V,i+1,V)
        elif x[i]-x[i-1]<=v and mem[i-1]==0:
            mem[i-1]=1
            go(mem,v,i-1,V)
        elif V>=1:
            for j in range(0,n[0]):
                if mem[j]==0:
                    go(mem,V/2,j,V/2)
        else:
            return 0
def chk(mem):
    for t in range(0,n[0]):
        if mem[t]!=1:
            return 0
    return 1