Buggy python submission (verdict: Runtime Error):
IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 4500
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        break
        pos = p[pos]
        if path[pos]: break # found closure
#    st = steps.index(pos) # start of closure
    st = 0
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
#    closure_scores = score(closure_path, C)
#    preclosure_scores = score(preclosure_path, C)
#    closure_score = sum(closure_scores)
#    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
#import random
#import itertools

IN = list(map(int, input().split())) N, K = IN[0], IN[1] P = [None] +
list(map(int, input().split())) C = [None] + list(map(int,
input().split())) MAX_N = 4500 #N = 1000 #K = 10**7 #P = [None] +
[random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i
in range(1, N+1)] #C = [None] + random.choices(range(-10**9, 10**9),
k=N)

verbose = False

def cumsum(a): tmp = [0]*(len(a)+1) for i in range(1, len(a)+1):
    tmp[i] = a[i-1] + tmp[i-1] return tmp[1:]

def find_cycle(p, pos): cnt = 0 steps = [0] * (MAX_N+1) path = [False]
    * (MAX_N+1) while True: steps[cnt] = pos path[pos] = True cnt += 1
    break pos = p[pos] if path[pos]: break # found closure # st =
    steps.index(pos) # start of closure st = 0 return [steps[:st],
    steps[st:cnt]]


def score(steps, c): ret = [0]*len(steps) for i in range(len(steps)):
    ret[i] = c[steps[i]] return ret

maxsc = -10**9-1 done = [False] * (N+1) for i in range(1, N+1): if
verbose: print('entering', i) if done[i]: continue [preclosure_path,
closure_path] = find_cycle(P, i) if verbose: print('closure found:',
closure_path) # closure_scores = score(closure_path, C) #
preclosure_scores = score(preclosure_path, C) # closure_score =
sum(closure_scores) # preclosure_len, closure_len =
len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len resid =
#    (K-preclosure_len)%closure_len if cycles>=1: cycles -= 1 abbrev =
#    closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3 path =
#    preclosure_path + closure_path*3 if verbose: print('score
#    trail:', trail) if verbose: print('path:', preclosure_path +
#    closure_path*3) if verbose: print('mark:', mark) mark = min(K,
#    len(preclosure_path+closure_path)+resid) localmax =
#    max(cumsum(trail[0:mark])) + max(0, closure_score*cycles) if
#    verbose: print('localmax:', localmax, 'cycles:', cycles) maxsc =
#    max(localmax, maxsc)

#    if verbose: print('going greedy') for j in range(1, closure_len):
#    if K<=mark+j: break target = path[j] if done[target]: continue
#    localmax = max(cumsum(trail[j:mark+j])) + max(0,
#    closure_score*cycles) maxsc = max(localmax, maxsc) done[target] =
#    True if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 4500
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        pos = p[pos]
        cnt += 1
        break
        if path[pos]: break # found closure
#    st = steps.index(pos) # start of closure
    st = 0
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
#    closure_scores = score(closure_path, C)
#    preclosure_scores = score(preclosure_path, C)
#    closure_score = sum(closure_scores)
#    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 4500
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        pos = p[pos]
        cnt += 1
        break
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
#    closure_scores = score(closure_path, C)
#    preclosure_scores = score(preclosure_path, C)
#    closure_score = sum(closure_scores)
#    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 4500
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        pos = p[pos]
        cnt += 1
        if path[pos]: break # found closure
    print(steps[:10])
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
#    closure_scores = score(closure_path, C)
#    preclosure_scores = score(preclosure_path, C)
#    closure_score = sum(closure_scores)
#    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 4500
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        pos = p[pos]
        cnt += 1
        if path[pos]: break # found closure
    st = steps.index(pos)-1 # start of closure
    return [steps[:st], steps[st:cnt-1]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
#    if verbose: print('closure found:', closure_path)
#    closure_scores = score(closure_path, C)
#    preclosure_scores = score(preclosure_path, C)
#    closure_score = sum(closure_scores)
#    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 4500
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
#    while True:
#        steps[cnt] = pos
#        pos = p[pos]
#        cnt += 1
#        if path[pos]:
#            break # found closure
#        else:
#            path[pos] = True
    st = steps.index(pos)-1 # start of closure
    return [steps[:st], steps[st:cnt-1]]

def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
#    if verbose: print('closure found:', closure_path)
#    closure_scores = score(closure_path, C)
#    preclosure_scores = score(preclosure_path, C)
#    closure_score = sum(closure_scores)
#    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 4500
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        pos = p[pos]
        cnt += 1
        if path[pos]:
            break # found closure
        else:
            path[pos] = True
    st = steps.index(pos)-1 # start of closure
    return [steps[:st], steps[st:cnt-1]]

def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
#    [preclosure_path, closure_path] = find_cycle(P, i)
    A = find_cycle(P, i)
#    if verbose: print('closure found:', closure_path)
#    closure_scores = score(closure_path, C)
#    preclosure_scores = score(preclosure_path, C)
#    closure_score = sum(closure_scores)
#    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 4500
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        pos = p[pos]
        cnt += 1
        if path[pos]:
            break # found closure
        else:
            path[pos] = True
    st = steps.index(pos)-1 # start of closure
    return [steps[:st], steps[st:cnt-1]]

def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
#    if verbose: print('closure found:', closure_path)
#    closure_scores = score(closure_path, C)
#    preclosure_scores = score(preclosure_path, C)
#    closure_score = sum(closure_scores)
#    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 1000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * MAX_N
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        pos = p[pos]
        cnt += 1
        if path[pos]:
            break # found closure
        else:
            path[pos] = True
    st = steps.index(pos)-1 # start of closure
    return [steps[:st], steps[st:cnt-1]]

def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
#    if verbose: print('closure found:', closure_path)
#    closure_scores = score(closure_path, C)
#    preclosure_scores = score(preclosure_path, C)
#    closure_score = sum(closure_scores)
#    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
#import random
#import itertools

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 1000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0]*MAX_N
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        pos = p[pos]
        cnt += 1
        if path[pos]:
            break # found closure
        else:
            path[pos] = True
    st = steps.index(pos)-1 # start of closure
    return [steps[:st], steps[st:cnt-1]]

def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
#    if verbose: print('entering', i)
#    if done[i]: continue
#    [preclosure_path, closure_path] = find_cycle(P, i)
#    if verbose: print('closure found:', closure_path)
#    closure_scores = score(closure_path, C)
#    preclosure_scores = score(preclosure_path, C)
#    closure_score = sum(closure_scores)
#    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
#import random
#import itertools

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 1000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0]*MAX_N
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        pos = p[pos]
        cnt += 1
        if path[pos]:
            break # found closure
        else:
            path[pos] = True
    st = steps.index(pos)-1 # start of closure
    return [steps[:st], steps[st:cnt-1]]

def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
#    if verbose: print('entering', i)
#    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
#    if verbose: print('closure found:', closure_path)
#    closure_scores = score(closure_path, C)
#    preclosure_scores = score(preclosure_path, C)
#    closure_score = sum(closure_scores)
#    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
#import random
#import itertools

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 1000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0]*MAX_N
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        pos = p[pos]
        cnt += 1
        if path[pos]:
            break # found closure
        else:
            path[pos] = True
    st = steps.index(pos)-1 # start of closure
    return [steps[:st], steps[st:cnt-1]]

def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
#import random
#import itertools

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 1000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0]*MAX_N
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        pos = p[pos]
        cnt += 1
        if path[pos]:
            break # found closure
        else:
            path[pos] = True
    st = steps.index(pos)-1 # start of closure
    return [steps[:st], steps[st:cnt-1]]

def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
#for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

#    cycles = (K-preclosure_len)//closure_len
#    resid = (K-preclosure_len)%closure_len
#    if cycles>=1: cycles -= 1
#    abbrev = closure_score * cycles
   
#    trail = preclosure_scores + closure_scores * 3
#    path = preclosure_path + closure_path*3
#    if verbose: print('score trail:', trail)
#    if verbose: print('path:', preclosure_path + closure_path*3)
#    if verbose: print('mark:', mark)
#    mark = min(K, len(preclosure_path+closure_path)+resid)
#    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
#    if verbose: print('localmax:', localmax, 'cycles:', cycles)
#    maxsc = max(localmax, maxsc)

#    if verbose: print('going greedy')
#    for j in range(1, closure_len):
#        if K<=mark+j: break
#        target = path[j]
#        if done[target]: continue
#        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
#        maxsc = max(localmax, maxsc)
#        done[target] = True
#        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
#import random
#import itertools

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 1000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0]*MAX_N
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        pos = p[pos]
        cnt += 1
        if path[pos]:
            break # found closure
        else:
            path[pos] = True
    st = steps.index(pos)-1 # start of closure
    return [steps[:st], steps[st:cnt-1]]

def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 4500
#N = 2000
#K = 10**7
#P = [None] + random.sample(range(1, N+1), k=N)
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False
g = {}
for i in range(1, N+1): g.update({i: P[i-1]})

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0]*MAX_N
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        pos = p[pos]
        cnt += 1
        if path[pos]:
            break # found closure
        else:
            path[pos] = True
    st = steps.index(pos)-1 # start of closure
    return [steps[:st], steps[st:cnt-1]]

def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
#MAX_N = 4500
#N = 2000
#K = 10**7
#P = [None] + random.sample(range(1, N+1), k=N)
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False
g = {}
for i in range(1, N+1): g.update({i: P[i-1]})

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0]*MAX_N
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        pos = p[pos]
        cnt += 1
        if path[pos]:
            break # found closure
        else:
            path[pos] = True
    st = steps.index(pos)-1 # start of closure
    return [steps[:st], steps[st:cnt-1]]

def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Time Limit Exceeded):
#import random

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
#N = 4500
#K = 10**9
#P = [None] + random.sample(range(1, N+1), k=N)
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False
g = {}
for i in range(1, N+1): g.update({i: P[i-1]})

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    pos = i
    cnt = 0
    steps, scores = [0]*(N+N+N+N), [0]*(N+N+N+N)
    path = [False] * (N+1)
    while True:
        steps[cnt] = pos
        scores[cnt] = C[pos]
        pos = P[pos]
        cnt += 1
        if path[pos]:
            break # found closure
        else:
            path[pos] = True
    if verbose: print('closure found')
    st = steps.index(pos) # start of closure
    if verbose: print('closure steps identified')
    closure_path = steps[st:cnt]
    closure_scores = scores[st:cnt]
    closure_score = sum(closure_scores)
    preclosure_len = st
    score_len = 0
    if verbose: print('closure path:', closure_path)
    closure_len = len(closure_path)
    cycles = (K-preclosure_len-closure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles >= 1: cycles -= 1
    if cycles<1:
        score_len = K
    else:
        score_len = preclosure_len + closure_len + 1 + closure_len + resid
#        score_len = K - closure_len*cycles + 1
    if (cycles > 0):
        scores[cnt] = closure_score*cycles
        cnt+=1
    for j in range(closure_len*3):
        if cnt+j>=len(scores): break
        scores[cnt+j] = closure_scores[j%closure_len]
    if verbose: print('preclosure:', preclosure_len,
                      'cycle len', closure_len,
                      'cycles:', cycles, 'resid:', resid)
    if verbose: print(i, ':', scores)
    localmax = max(cumsum(scores[0:(score_len)]))
    maxsc = max(localmax, maxsc)
    if verbose: print(i, ': done with', localmax, 'score_len:', score_len)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        target = steps[j]
        if done[target]: continue
        localmax = max(cumsum(scores[j:(score_len+j)]))
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
#import random

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
#N = 4500
#K = 10**9
#P = [None] + random.sample(range(1, N+1), k=N)
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False
g = {}
for i in range(1, N+1): g.update({i: P[i-1]})

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    pos = i
    cnt = 0
    steps, scores = [0]*(N+N+N+N), [0]*(N+N+N+N)
    path = [False] * (N+1)
    while True:
        steps[cnt] = pos
        scores[cnt] = C[pos]
        pos = P[pos]
        cnt += 1
        if path[pos]:
            break # found closure
        else:
            path[pos] = True
    if verbose: print('closure found')
    st = steps.index(pos) # start of closure
    if verbose: print('closure steps identified')
    closure_path = steps[st:cnt]
    closure_scores = scores[st:cnt]
    closure_score = sum(closure_scores)
    preclosure_len = st
    score_len = 0
    if verbose: print('closure path:', closure_path)
    closure_len = len(closure_path)
    cycles = (K-preclosure_len-closure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles >= 1: cycles -= 1
    if cycles<1:
        score_len = K
    else:
        score_len = preclosure_len + closure_len + 1 + closure_len + resid
#        score_len = K - closure_len*cycles + 1
    if (cycles > 0):
        scores[cnt] = closure_score*cycles
        cnt+=1
    for j in range(closure_len*3):
        if cnt+j>len(scores): break
        scores[cnt+j] = closure_scores[j%closure_len]
    if verbose: print('preclosure:', preclosure_len,
                      'cycle len', closure_len,
                      'cycles:', cycles, 'resid:', resid)
    if verbose: print(i, ':', scores)
    localmax = max(cumsum(scores[0:(score_len)]))
    maxsc = max(localmax, maxsc)
    if verbose: print(i, ': done with', localmax, 'score_len:', score_len)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        target = steps[j]
        if done[target]: continue
        localmax = max(cumsum(scores[j:(score_len+j)]))
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
import random

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
#N = 45
#K = 10**8
#P = random.sample(range(1, N+1), k=N)
#C = [None] + random.choices(range(-10**8, 10**8), k=N)

verbose = False
g = {}
for i in range(1, N+1): g.update({i: P[i-1]})

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

maxsc = -10**9-1
for i in range(1, N+1):
    if verbose: print('entering', i)
    pos = i
    cnt = 0
    steps, scores = [0]*(N+N+N), [0]*(N+N+N)
    path = set()
    while True:
        steps[cnt] = pos
        scores[cnt] = C[pos]
        pos = g[pos]
        cnt += 1
        if pos in steps: break # found closure
    if verbose: print('closure found')
    st = steps.index(pos) # start of closure
    if verbose: print('closure steps identified')
    closure_path = steps[st:cnt]
    closure_scores = scores[st:cnt]
    closure_score = sum(closure_scores)
    preclosure_len = st
    score_len = 0
    if verbose: print('closure path:', closure_path)
    closure_len = len(closure_path)
    cycles = (K-preclosure_len)//closure_len
    if cycles >= 1: cycles -= 1
    if cycles == 0:
        score_len = K
    else:
        score_len = preclosure_len + 1 + closure_len*cycles + resid
    resid = (K-preclosure_len)%closure_len
    if (cycles > 0):
        scores[cnt] = closure_score*cycles
        cnt+=1
    for j in range(K-preclosure_len-closure_len-closure_len*cycles):
        scores[cnt+j] = closure_scores[j%closure_len]
    if verbose: print('preclosure:', preclosure_len,
                      'cycles:', cycles, 'resid:', resid)
    if verbose: print(i, ':', scores)
    maxsc = max(max(cumsum(scores[0:score_len])), maxsc)
    if verbose: print(i, ': done, score_len:', score_len)


print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = list(map(int, input().split()))
C = [None] + list(map(int, input().split()))

g = {}
for i in range(1, N+1): g.update({i: P[i-1]})

def cumsum(a):
    tmp = [0]
    for i in range(1, len(a)+1): tmp.append(a[i-1] + tmp[i-1])
    return tmp[1:]

maxsc = -10**9-1
for i in range(1, N+1):
    pos = i
    steps, scores = [], []
    path = set()
    while True:
        steps.append(pos)
        scores.append(C[pos])
        pos = g[pos]
        if pos in steps: break # found closure
    st = steps.index(pos) # start of closure
    closure_path = steps[st:]
    closure_score = scores[st:]
    closure_len = len(closure_path)
    cycles = int(K/closure_len)+1
    steps += closure_path * cycles
    scores += closure_score *cycles
    maxsc = max(max(cumsum(scores[0:K])), maxsc)

print(maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Runtime Error):
import networkx as nx
import networkx.algorithms.cycles
from collections import deque

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = list(map(int, input().split()))
C = [0]+list(map(int, input().split()))

g = nx.DiGraph()
g.add_nodes_from(range(1, N+1))

edges = []
for i in range(1, N+1): edges.append((i, P[i-1]))
g.add_edges_from(edges)

class cy:
    def __init__(self, steps, scores, to=None):
        self.steps = deque(steps)
        self.scores = deque(scores)
        if to==None:
            self.isCycle = True
        else:
            self.to = to
            self.isCycle = False    

CY = [None]*(N+1)
cpath = set()
for cycle in networkx.algorithms.cycles.simple_cycles(g):
    steps = deque(cycle)
    cpath.update(steps)
    scores = deque([C[i] for i in cycle])
    for i in cycle:
        rot = steps.index(i)
        steps.rotate(-rot)
        scores.rotate(-rot)
        CY[i] = cy(steps, scores)

P = [0] + P
for i in range(1, N+1):
    if CY[i] != None: continue # in closure
    steps, scores = [], []
    pos = i
    to = 0
    while True:
        steps.append(pos)
        scores.append(C[pos])
        pos = P[pos]
        if pos in cpath:
            CY[i] = cy(steps, scores, pos)
            break

maxsc = -10**9-1
for i in range(1, N+1):
    path = []
    pos = i
    if not CY[pos].isCycle: # out of closure
        path += list(CY[i].scores)
        pos = CY[i].to
    path += list(CY[i].scores) * ( int(K/len(CY[i].scores))+1 )
    path = path[0:K] # curtail
    score = [0]
    for j in range(len(path)): score.append(score[j]+path[j])
    maxsc = max([maxsc] + score[1:len(score)])

print (maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)

Buggy python submission (verdict: Time Limit Exceeded):
IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = list(map(int, input().split()))
C = list(map(int, input().split()))

maxsc = -1*10**9
init = True
for i in range(1, N+1):
    pos, score = i, 0
    for st in range(K):
        score += C[pos-1]
        pos = P[pos-1]
        maxsc = max(maxsc, score)
print (maxsc)


Fixed submission:

IN = list(map(int, input().split()))
N, K = IN[0], IN[1]
P = [None] + list(map(int, input().split()))
C = [None] + list(map(int, input().split()))
MAX_N = 45000
#N = 1000
#K = 10**7
#P = [None] + [random.choice(list(itertools.chain(range(1,i), range(i+1,N)))) for i in range(1, N+1)]
#C = [None] + random.choices(range(-10**9, 10**9), k=N)

verbose = False

def cumsum(a):
    tmp = [0]*(len(a)+1)
    for i in range(1, len(a)+1): tmp[i] = a[i-1] + tmp[i-1]
    return tmp[1:]

def find_cycle(p, pos):
    cnt = 0
    steps = [0] * (MAX_N+1)
    path = [False] * (MAX_N+1)
    while True:
        steps[cnt] = pos
        path[pos] = True
        cnt += 1
        pos = p[pos]
        if path[pos]: break # found closure
    st = steps.index(pos) # start of closure
    return [steps[:st], steps[st:cnt]]


def score(steps, c):
    ret = [0]*len(steps)
    for i in range(len(steps)): ret[i] = c[steps[i]]
    return ret

maxsc = -10**9-1
done = [False] * (N+1)
for i in range(1, N+1):
    if verbose: print('entering', i)
    if done[i]: continue
    [preclosure_path, closure_path] = find_cycle(P, i)
    if verbose: print('closure found:', closure_path)
    closure_scores = score(closure_path, C)
    preclosure_scores = score(preclosure_path, C)
    closure_score = sum(closure_scores)
    preclosure_len, closure_len = len(preclosure_path), len(closure_path)

    cycles = (K-preclosure_len)//closure_len
    resid = (K-preclosure_len)%closure_len
    if cycles>=1: cycles -= 1
    abbrev = closure_score * cycles
   
    trail = preclosure_scores + closure_scores * 3
    path = preclosure_path + closure_path*3
    if verbose: print('score trail:', trail)
    if verbose: print('path:', preclosure_path + closure_path*3)
    if verbose: print('mark:', mark)
    mark = min(K, len(preclosure_path+closure_path)+resid)
    localmax = max(cumsum(trail[0:mark])) + max(0, closure_score*cycles)
    if verbose: print('localmax:', localmax, 'cycles:', cycles)
    maxsc = max(localmax, maxsc)

    if verbose: print('going greedy')
    for j in range(1, closure_len):
        if K<=mark+j: break
        target = path[j]
        if done[target]: continue
        localmax = max(cumsum(trail[j:mark+j])) + max(0, closure_score*cycles)
        maxsc = max(localmax, maxsc)
        done[target] = True
        if verbose: print('done:', target, 'with', localmax)

print(maxsc)