Problem:


Score : 400 points

Problem Statement

Takahashi will play a game using a piece on an array of squares numbered 1, 2, \cdots, N. Square i has an integer C_i written on it. Also, he is given a permutation of 1, 2, \cdots, N: P_1, P_2, \cdots, P_N.

Now, he will choose one square and place the piece on that square. Then, he will make the following move some number of times between 1 and K (inclusive):

In one move, if the piece is now on Square i (1 \leq i \leq N), move it to Square P_i. Here, his score increases by C_{P_i}.

Help him by finding the maximum possible score at the end of the game. (The score is 0 at the beginning of the game.)

Constraints

2 \leq N \leq 5000

1 \leq K \leq 10^9

1 \leq P_i \leq N

P_i \neq i

P_1, P_2, \cdots, P_N are all different.

-10^9 \leq C_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K
P_1 P_2 \cdots P_N
C_1 C_2 \cdots C_N

Output

Print the maximum possible score at the end of the game.

Sample Input 1

5 2
2 4 5 1 3
3 4 -10 -8 8

Sample Output 1

8

When we start at some square of our choice and make at most two moves, we have the following options:

If we start at Square 1, making one move sends the piece to Square 2, after which the score is 4. Making another move sends the piece to Square 4, after which the score is 4 + (-8) = -4.

If we start at Square 2, making one move sends the piece to Square 4, after which the score is -8. Making another move sends the piece to Square 1, after which the score is -8 + 3 = -5.

If we start at Square 3, making one move sends the piece to Square 5, after which the score is 8. Making another move sends the piece to Square 3, after which the score is 8 + (-10) = -2.

If we start at Square 4, making one move sends the piece to Square 1, after which the score is 3. Making another move sends the piece to Square 2, after which the score is 3 + 4 = 7.

If we start at Square 5, making one move sends the piece to Square 3, after which the score is -10. Making another move sends the piece to Square 5, after which the score is -10 + 8 = -2.

The maximum score achieved is 8.

Sample Input 2

2 3
2 1
10 -7

Sample Output 2

13

Sample Input 3

3 3
3 1 2
-1000 -2000 -3000

Sample Output 3

-1000

We have to make at least one move.

Sample Input 4

10 58
9 1 6 7 8 4 3 2 10 5
695279662 988782657 -119067776 382975538 -151885171 -177220596 -169777795 37619092 389386780 980092719

Sample Output 4

29507023469

The absolute value of the answer may be enormous.



Sample input:
5 2
2 4 5 1 3
3 4 -10 -8 8


Sample output:
8

Submission status: Time Limit Exceeded

Solution code:
N, K = map(int, input().split())
p = list(map(int, input().split()))
c = list(map(int, input().split()))

ans = []
grp = []

for i in range(N):
    visited = [0]*N
    visited[i] = 1
    lst = [i] 
    j = i
    k = 1
    jdg = False
    plst = [0]

    while k <= K:
        k += 1
        if visited[p[j]-1] != 0:
            lst.append(p[j]-1)
            if p[j]-1 == i: plst.append(plst[-1] + c[p[j]-1])
            jdg = True
            break
        else:
            visited[p[j]-1] = 1
            lst.append(p[j]-1)
            plst.append(plst[-1] + c[p[j]-1])
            j = p[j]-1
    if jdg:
        pnt2 = 0
        for l, m in enumerate(lst):
            if m == lst[-1]: break

        pnt3 = plst[-1] - plst[l]
        if pnt3 > 0:
            if (K - l) > 2 * (len(lst) - l - 1):
                plst.append(plst[-1] + (((K - l)// (len(lst) - l - 1)) - 1) * pnt3)
                k += (((K-l) // (len(lst)-l-1))-1) * (len(lst)-l-1)

            for m in range(l, K-k+l+1):
                plst.append(plst[-1] + c[p[lst[m]]-1])
    pnt = max(plst[1:])
    ans.append(pnt)
print(max(ans))

Submission status: Time Limit Exceeded

Solution code:
n,k=map(int,input().split())
p=list(map(int,input().split()))
c=list(map(int,input().split()))
for i in range(n):
    p[i]-=1
ans=max(c)
for i in range(n):
    f=i
    r=0
    l=[]
    while True:
        f=p[f]
        l.append(c[f])
        r+=c[f]
        if f==i:
            break
    t=0
    for j in range(len(l)):
        t+=l[j]
        if j+1>k:
            break
        ret=t
        if r>0:
            e=(k-j-1)//len(l)
            ret+=r*e
        ans=max(ans,ret)
print(ans)

Submission status: Time Limit Exceeded

Solution code:
N, K = [int(x) for x in input().split()]
P = [0] + [int(x) for x in input().split()]
C = [0] + [int(x) for x in input().split()]

max_score = max(C[1:])
for init in range(1, N + 1):   # 初めの場所をinitとする
    score = [0]  # k回移動後のスコア
    i = init
    for k in range(1, K + 1):
        i = P[i]  # k回移動後に着くところ
        score.append(score[-1] + C[i])
        max_score = max(max_score, score[k])
        if i == init:  # ループ検出
            loop_score = score[-1]
            loop_len = k
            if loop_score > 0:
                max_score = max(max_score, max(score[j] + loop_score * ((K - j) // loop_len) for j in range(1, loop_len + 1)))
            break

print(max_score)

Submission status: Time Limit Exceeded

Solution code:
n, k = map(int, input().split())
p = list(map(int, input().split()))
p = [_p-1 for _p in p]
c = list(map(int, input().split()))

ans = -float('inf')

visited = [False] * n
ss = []
for i in range(n):
    if visited[i]: continue
    cur = i
    s = []
    while not visited[cur]:
        visited[cur] = True
        s.append(c[cur])
        cur = p[cur]
    ss.append(s)

for s in ss:
    m = len(s)
    cumsum = [0] * (m*2+1)
    for i in range(2*m):
        cumsum[i+1] = cumsum[i] + s[i%m]
    
    amari = [-float('inf')] * m
    for i in range(m):
        for j in range(m):
            amari[j] = max(amari[j], cumsum[i+j] - cumsum[i])
    
    for r in range(0, m):
        if r > k: continue
        q = (k-r)//m
        if r==0 and q==0:
            continue
        
        if cumsum[m] > 0:
            ans = max(ans, amari[r] + cumsum[m]*q)
        elif r > 0:
            ans = max(ans, amari[r])

print(ans)

Submission status: Time Limit Exceeded

Solution code:
N,K=map(int,input().split())
pbox=list(map(int,input().split()))
cbox=list(map(int,input().split()))
ans=[]
abox=[]

for i in range(N):
    temp=pbox[i]
    ans.append(cbox[temp-1])
    for j in range(K-1):
        temp=pbox[temp-1]
        ans.append(cbox[temp-1]+ans[-1])
    abox.append(max(ans))
print(max(abox))

Submission status: Time Limit Exceeded

Solution code:
import itertools
import numpy as np

if __name__ == "__main__":

	N,K = map(int,input().split())
	P = [ int(p)-1 for p in input().split() ]
	C = list(map(int,input().split()))

	# print(P)
	# 一度計算したサイクル情報をキャッシュしておくための配列
	cycleIDs = np.full( N, -1, np.int64 )
	cycleInfs = []
	cycleID = 0

	for n in range(N):

		v = n

		if cycleIDs[v] != -1:
			continue
		else:
			currentCycleItemCnt = 0
			currentCycleCosts = []
			while True:
				# 全頂点について、属するサイクルを計算する
				currentCycleItemCnt += 1
				currentCycleCosts.append( C[v] )
				cycleIDs[v] = cycleID

				v = P[v]
				if v == n:
					# サイクル発見
					cycleInfs.append( (currentCycleItemCnt, np.array( currentCycleCosts ) ) )
					cycleID += 1
					break


	scores = []
	for cycleID in cycleIDs:

		currentCycleItemCnt = cycleInfs[cycleID][0]
		currentCycleCosts = cycleInfs[cycleID][1]
		currentCycleTotalScore = np.sum(currentCycleCosts)

		# ループを含めない最大の処理回数
		procCnt = K % currentCycleItemCnt
		# ただし、割り切れる場合も、1サイクル分は処理するものとする
		# (1回以上はやらなければならないのを考慮？)
		if procCnt == 0:
			procCnt = currentCycleItemCnt

		# サイクル内でループしてスコアを稼ぐ場合の考慮
		loopScore = 0
		if currentCycleTotalScore > 0:
			cycleLoopCnt =  ( K - procCnt ) // currentCycleItemCnt
			loopScore = cycleLoopCnt * currentCycleTotalScore

		# このサイクルに属する全頂点分をまとめて計算する
		for i in range(currentCycleItemCnt):
			# 累積和
			# acc = list(itertools.accumulate( np.roll( currentCycleCosts, i )[:procCnt] ) )
			scores.append( max( itertools.accumulate( np.roll( currentCycleCosts, i )[:procCnt] ) ) + loopScore )

	print(max(scores))

Submission status: Time Limit Exceeded

Solution code:
import itertools
import numpy as np

if __name__ == "__main__":

	N,K = map(int,input().split())
	P = [ int(p)-1 for p in input().split() ]
	C = list(map(int,input().split()))

	# print(P)
	# 一度計算したサイクル情報をキャッシュしておくための配列
	cycleIDs = np.full( N, -1, np.int64 )
	cycleInfs = []

	ans = -10 ** 9
	cycleID = 0

	for n in range(N):

		v = n

		if cycleIDs[v] != -1:
			currentCycleItemCnt, currentCycleTotal = cycleInfs[ cycleIDs[v] ]
			# print(currentCycleItemCnt, currentCycleTotal)
		else:
			currentCycleItemCnt = 0
			currentCycleCosts = []
			while True:
				# 全頂点について、属するサイクルを計算する
				currentCycleItemCnt += 1
				currentCycleCosts.append( C[v] )

				v = P[v]
				if v == n:
					# サイクル発見
					cycleInfs.append( (currentCycleItemCnt, np.array( currentCycleCosts ) ) )
					cycleID += 1
					break

				# 一応、一度サイクルを計算した頂点については、
				# その頂点の属するサイクルの情報をメモっておく。。。
				cycleIDs[v] = cycleID

	scores = []
	for cycleID in cycleIDs:

		currentCycleItemCnt = cycleInfs[cycleID][0]
		currentCycleCosts = cycleInfs[cycleID][1]
		currentCycleTotalScore = np.sum(currentCycleCosts)

		# ループを含めない最大の処理回数
		procCnt = K % currentCycleItemCnt
		# ただし、割り切れる場合も、1サイクル分は処理するものとする
		# (1回以上はやらなければならないのを考慮？)
		if procCnt == 0:
			procCnt = currentCycleItemCnt

		# サイクル内でループしてスコアを稼ぐ場合の考慮
		loopScore = 0
		if currentCycleTotalScore > 0:
			cycleLoopCnt =  ( K - procCnt ) // currentCycleItemCnt
			loopScore = cycleLoopCnt * currentCycleTotalScore

		# このサイクルに属する全頂点分をまとめて計算する
		for i in range(currentCycleItemCnt):
			# 累積和
			# acc = list(itertools.accumulate( np.roll( currentCycleCosts, i )[:procCnt] ) )
			scores.append( max( itertools.accumulate( np.roll( currentCycleCosts, i )[:procCnt] ) ) + loopScore )

	print(max(scores))

Submission status: Time Limit Exceeded

Solution code:
import itertools
import numpy as np

if __name__ == "__main__":

	N,K = map(int,input().split())
	P = [ int(p)-1 for p in input().split() ]
	C = list(map(int,input().split()))

	# print(P)
	# 一度計算したサイクル情報をキャッシュしておくための配列
	cycleIDs = np.full( N, -1, np.int64 )
	cycleInfs = []

	ans = -10 ** 9
	cycleID = 0

	for n in range(N):

		v = n

		if cycleIDs[v] != -1:
			currentCycleItemCnt, currentCycleTotal = cycleInfs[ cycleIDs[v] ]
			# print(currentCycleItemCnt, currentCycleTotal)
		else:
			currentCycleItemCnt = 0
			currentCycleCosts = []
			while True:
				# 全頂点について、属するサイクルを計算する
				currentCycleItemCnt += 1
				currentCycleCosts.append( C[v] )

				v = P[v]
				if v == n:
					# サイクル発見
					cycleInfs.append( (currentCycleItemCnt, currentCycleCosts ) )
					cycleID += 1
					break

				# 一応、一度サイクルを計算した頂点については、
				# その頂点の属するサイクルの情報をメモっておく。。。
				cycleIDs[v] = cycleID

	for cycleID in cycleIDs:

		currentCycleItemCnt = cycleInfs[cycleID][0]
		currentCycleCosts = np.array( cycleInfs[cycleID][1] )
		currentCycleTotalScore = np.sum(currentCycleCosts)

		# ループを含めない最大の処理回数
		procCnt = K % currentCycleItemCnt
		# ただし、割り切れる場合も、1サイクル分は処理するものとする
		# (1回以上はやらなければならないのを考慮？)
		if procCnt == 0:
			procCnt = currentCycleItemCnt
		# procCnt = min( K, procCnt )

		# サイクル内でループしてスコアを稼ぐ場合の考慮
		cycleLoopCnt = 0
		if currentCycleTotalScore > 0:
			# その時、ループが発生した方がスコアが高くなる場合
			# ループ回数を計算
			cycleLoopCnt =  ( K - procCnt ) // currentCycleItemCnt
			# print("K - procCnt=", K - procCnt, "currentCycleItemCnt=", currentCycleItemCnt)
			# print("cycleLoopCnt=", cycleLoopCnt)


		# このサイクル内での最大スコア
		currentCycleMaxScore = -10 ** 9

		# このサイクルに属する全頂点分をまとめて計算する
		# まず、ループが発生しない分まで計算

		for i in range(currentCycleItemCnt):
			# 累積和
			acc = list(itertools.accumulate( np.roll( currentCycleCosts, i )[:procCnt] ) )

			# print(i, acc)#[:procCnt])
			currentCycleMaxScore = max( currentCycleMaxScore, max( acc ) )
		# print("currentCycleMaxScore=",currentCycleMaxScore)


		currentCycleMaxScore += cycleLoopCnt * currentCycleTotalScore
		# print("v=", v, "currentCycleItemCnt=", currentCycleItemCnt, "procCnt, cycleLoopCnt, currentCycleMaxScore,currentCycleTotalScore=", procCnt, cycleLoopCnt, currentCycleMaxScore,currentCycleTotalScore)

		ans = max( ans, currentCycleMaxScore )

	print(ans)

Submission status: Time Limit Exceeded

Solution code:
import itertools
import numpy as np

if __name__ == "__main__":

	N,K = map(int,input().split())
	P = [ int(p)-1 for p in input().split() ]
	C = list(map(int,input().split()))

	# 計算済み
	used = [ False for _ in range(N) ]

	# print(P)
	# 一度計算したサイクル情報を一応キャッシュしておく。。。
	cycleIDs = [ -1 for _ in range(N) ]
	cycleInfs = []

	ans = -10 ** 9
	cycleID = 0

	for n in range(N):

		v = n

		currentCycleItemCnt = 0
		currentCycleCosts = []

		if cycleIDs[v] != -1:
			currentCycleItemCnt, currentCycleTotal = cycleInfs[ cycleIDs[v] ]
			# print(currentCycleItemCnt, currentCycleTotal)
		else:
			while True:
				# 全頂点について、属するサイクルを計算する
				currentCycleItemCnt += 1
				currentCycleCosts.append( C[v] )

				v = P[v]
				if v == n:
					# サイクル発見
					cycleInfs.append( (currentCycleItemCnt, currentCycleCosts ) )
					cycleID += 1
					break

				# 一応、一度サイクルを計算した頂点については、
				# その頂点の属するサイクルの情報をメモっておく。。。
				cycleIDs[v] = cycleID

	for cycleID in cycleIDs:

		currentCycleItemCnt = cycleInfs[cycleID][0]
		currentCycleCosts = cycleInfs[cycleID][1]
		currentCycleTotalScore = sum(currentCycleCosts)

		# ループを含めない最大の処理回数
		procCnt = K % currentCycleItemCnt
		# ただし、割り切れる場合も、1サイクル分は処理するものとする
		# (1回以上はやらなければならないのを考慮？)
		if procCnt == 0:
			procCnt = currentCycleItemCnt
		# procCnt = min( K, procCnt )

		# サイクル内でループしてスコアを稼ぐ場合の考慮
		cycleLoopCnt = 0
		if currentCycleTotalScore > 0:
			# その時、ループが発生した方がスコアが高くなる場合
			# ループ回数を計算
			cycleLoopCnt =  ( K - procCnt ) // currentCycleItemCnt
			# print("K - procCnt=", K - procCnt, "currentCycleItemCnt=", currentCycleItemCnt)
			# print("cycleLoopCnt=", cycleLoopCnt)


		# このサイクル内での最大スコア
		currentCycleMaxScore = -10 ** 9

		# このサイクルに属する全頂点分をまとめて計算する
		# まず、ループが発生しない分まで計算
		npCosts = np.array( currentCycleCosts )

		for i in range(currentCycleItemCnt):
			# 累積和
			acc = list(itertools.accumulate( np.roll( npCosts, i )[:procCnt] ) )

			# print(i, acc)#[:procCnt])
			currentCycleMaxScore = max( currentCycleMaxScore, max( acc ) )
		# print("currentCycleMaxScore=",currentCycleMaxScore)


		currentCycleMaxScore += cycleLoopCnt * currentCycleTotalScore
		# print("v=", v, "currentCycleItemCnt=", currentCycleItemCnt, "procCnt, cycleLoopCnt, currentCycleMaxScore,currentCycleTotalScore=", procCnt, cycleLoopCnt, currentCycleMaxScore,currentCycleTotalScore)

		ans = max( ans, currentCycleMaxScore )

	print(ans)

Submission status: Time Limit Exceeded

Solution code:
# -*- coding: utf-8 -*-
# モジュールのインポート
import sys
import math

# 標準入力を取得
N, K = list(map(int, input().split()))
P = list(map(int, input().split()))
C = list(map(int, input().split()))

# 求解処理
P = [P[i] - 1 for i in range(N)]
ans = -sys.maxsize
for i in range(N):
    pos = i
    S = []
    score = 0
    while True:
        pos = P[pos]
        score += C[pos]
        S.append(score)
        if pos == i:
            break
    length = len(S)
    circ_S = S[-1]

    if circ_S <= 0:
        ans = max(ans, max(S[:min(K, length)]))
    else:
        circ_cnt = int(K / length)
        if K % length == 0:
            ans = max(ans, (circ_cnt - 1) * circ_S + max(S))
        else:
            ans = max(ans, circ_cnt * circ_S + max(S[:(K % length)]))

# 結果出力
print(ans)

Submission status: Time Limit Exceeded

Solution code:
# -*- coding: utf-8 -*-
# モジュールのインポート
import sys
import math

# 標準入力を取得
N, K = list(map(int, input().split()))
P = list(map(int, input().split()))
C = list(map(int, input().split()))

# 求解処理
ans = -sys.maxsize
for i in range(N):
    pos = i
    S = []
    score = 0
    while True:
        pos = P[pos] - 1
        score += C[pos]
        S.append(score)
        if pos == i:
            break
    length = len(S)
    circ_S = S[-1]

    if circ_S <= 0:
        ans = max(ans, max(S[:min(K, length)]))
    else:
        circ_cnt = int(K / length)
        if K % length == 0:
            ans = max(ans, (circ_cnt - 1) * circ_S + max(S))
        else:
            ans = max(ans, circ_cnt * circ_S + max(S[:(K % length)]))

# 結果出力
print(ans)

Submission status: Time Limit Exceeded

Solution code:
N,K = map(int,input().split())
P = list(map(int,input().split()))
C = list(map(int,input().split()))

ans = -float('inf')
v = []
for n in range(N):
    loop, score = 0, 0
    t = n
    for i in range(min(N, K)):
        n = P[n]-1
        score += C[n]
        ans = max(ans, score)
        if n == t:
            loop = i+1
            break
    v.append((loop, score))

for n in range(N):
    loop, score = v[n]
    if loop > 0 and score > 0:
        r = (K-1)//loop
        nscore = r*score
        for i in range(K-r*loop):
            n = P[n]-1
            nscore += C[n]
            ans = max(nscore, ans)
print(ans)

Submission status: Time Limit Exceeded

Solution code:
N, K = map(int,input().split())
p = list(map(int,input().split()))
c = list(map(int,input().split()))
K = K-1
ans = -10**9-1
for h in range(N):
   i = h+1
   start = i
   circle = [c[i-1]]
   i = p[i-1]
   while i != start:
      score = circle[-1] + c[i-1]
      circle.append(score)
      i = p[i-1]
   l=len(circle)
   for j in range(min(l, K+1)):
      if circle[l-1] > 0:
         score = circle[j] + ((K - j)//l)*circle[l-1]
      else:
         score = circle[j]
      ans = max(score, ans)      
print(ans)

Submission status: Time Limit Exceeded

Solution code:
N, K = map(int,input().split())
p = list(map(int,input().split()))
c = list(map(int,input().split()))
K = K-1
ans = -10**9-1
i = 0
for h in range(N):
   i += 1
   start = i
   circle = [c[i-1]]
   i = p[i-1]
   while i != start:
      score = circle[-1] + c[i-1]
      circle.append(score)
      i = p[i-1]
   l=len(circle)
   for j in range(min(l, K+1)):
      if circle[l-1] > 0:
         score = circle[j] + ((K - j)//l)*circle[l-1]
      else:
         score = circle[j]
      ans = max(score, ans)      
print(ans)

Submission status: Time Limit Exceeded

Solution code:
N, K = map(int,input().split())
p = list(map(int,input().split()))
c = list(map(int,input().split()))
K = K-1
ans = -10**9-1
i = 0
for h in range(N):
   i += 1
   start = i
   circle = [c[i-1]]
   i = p[i-1]
   while i != start:
      l = len(circle)
      score = circle[l-1] + c[i-1]
      circle.append(score)
      i = p[i-1]
   l=len(circle)
   for j in range(min(l, K+1)):
      if circle[l-1] > 0:
         score = circle[j] + ((K - j)//l)*circle[l-1]
      else:
         score = circle[j]
      ans = max(score, ans)      
print(ans)

Submission status: Time Limit Exceeded

Solution code:
N, K = map(int,input().split())
p = list(map(int,input().split()))
c = list(map(int,input().split()))
K = K-1
ans = -10**9-1
for i in range(N):
   i += 1
   start = i
   circle = [c[i-1]]
   i = p[i-1]
   while i != start:
      l = len(circle)
      score = circle[l-1] + c[i-1]
      circle.append(score)
      i = p[i-1]
   l=len(circle)
   for j in range(min(l, K+1)):
      if circle[l-1] > 0:
         score = circle[j] + ((K - j)//l)*circle[l-1]
      else:
         score = circle[j]
      ans = max(score, ans)      
print(ans)

Submission status: Time Limit Exceeded

Solution code:
#D - Moving_piece
N,K = map(int,input().split())
P =[]
C =[]
P = list(map(int,input().split()))
C = list(map(int,input().split()))
ichi  = 0
score_max = -1000000010
i = 0
for i in range(N):
    ichi = i
    score = 0
    step  = K
    while step > 0:
        if i != P[ichi] or score >= 0:
            ichi = P[ichi] -1
            score += C[ichi]
            if score > score_max:
                score_max = score
            step -= 1
        else:
            step = 0
# 出力
print(score_max)

Submission status: Time Limit Exceeded

Solution code:
from numba import jit

n,k=map(int,input().split())
P=list(map(int,input().split()))
P=[p-1 for p in P]
C=list(map(int,input().split()))

@jit
def main():
  ans=-float('inf')
  for si in range(n):
    x=si
    S=[]
    tot=0
    while True:
      x=P[x]
      S.append(C[x])
      tot+=C[x]
      if x==si:
        break
    l=len(S)
    t=0
    for i in range(l):
      t+=S[i]
      if i+1>k:
        break
      now=t
      if tot>0:
        e=(k-i-1)//l
        now+=tot*e
      ans=max(ans,now)
  return ans      


print(main())

Submission status: Time Limit Exceeded

Solution code:
def main():
  ans=-float('inf')
  for si in range(n):
    x=si
    S=[]
    tot=0
    while True:
      x=P[x]
      S.append(C[x])
      tot+=C[x]
      if x==si:
        break
    l=len(S)
    t=0
    for i in range(l):
      t+=S[i]
      if i+1>k:
        break
      now=t
      if tot>0:
        e=(k-i-1)//l
        now+=tot*e
      ans=max(ans,now)
  return ans
        
      

n,k=map(int,input().split())
P=list(map(int,input().split()))
P=[p-1 for p in P]
C=list(map(int,input().split()))
flag=[0]*n


print(main())

Submission status: Time Limit Exceeded

Solution code:
N,K = map(int,input().split())
P = list(map(int,input().split()))
C = list(map(int,input().split()))
result = []
for i in range(1,N+1):
  y = 0
  x = i
  for j in range(1,K+1): 
    x = P[x-1]
    y = y+C[x-1]
    result.append(y)    
  
print(max(result))

Submission status: Time Limit Exceeded

Solution code:
N , K = ( int(x) for x in input().split() )
P = list( int(x) for x in input().split() )
C = list( int(x) for x in input().split() )

loop_num = [ 0 for i in range( N ) ]
loop_val = [ 0 for i in range( N ) ]

each_max = [ 0 for i in range( N ) ]

x = 1
num = 0
val = 0
for i in range( N ):
    num = 0
    val = 0
    x = i - 1
    flag = 0
    while x != i:
        if flag == 0:
            x = i
            flag += 1
        
        x = P[x] - 1
        num += 1
        val += C[x]

    loop_num[i] = num
    loop_val[i] = val
    if K < num:
        maxx = -float('inf')
        value = 0
        x = i
        for j in range( K ):
            x = P[x] - 1
            value += C[x]
            if maxx < value:
                maxx = value
        each_max[i] = maxx
    else:
        maxx = -float('inf')
        value = 0
        x = i
        for j in range( num ):
            x = P[x] - 1
            value += C[x]
            if maxx < value:
                maxx = value

        sho = K // num
        amari = K % num
        max_ = val * sho
        max_dash = 0
        value = 0
        x = i
        for j in range( amari ):
            x = P[x] - 1
            value += C[x]
            if max_dash < value:
                max_dash = value
        max_ += max_dash
        each_max[i] = max( maxx , max_ )



#print(loop_num,loop_val)

print( int( max(each_max) ) )

Submission status: Time Limit Exceeded

Solution code:
N, K = map(int, input().split())
P = [0] + list(map(int, input().split()))
C = [0] + list(map(int, input().split()))

answer = -float('inf')
for start_p in range(1, N+1):

    cycle_total_score = 0
    cycle_in_score = -float('inf')
    cycle_count = 0
    next_p = P[start_p]
    while True:
        cycle_total_score += C[next_p]
        cycle_in_score = max(cycle_in_score, cycle_total_score)
        cycle_count += 1

        if next_p == start_p:
            # print('start_p:', start_p, ' cycle_total_score:', cycle_total_score, 'cycle_in_score:', cycle_in_score, 'cycle_count:', cycle_count)
            break
        next_p = P[next_p]

    max_score = 0
    if K == cycle_count:
        max_score = cycle_in_score
    else:
        #あふれたK % cycle_count回数分だけスコアを足すためにmaxを探さす
        add_max_count = K % cycle_count
        add_total_score = 0
        add_score = -float('inf')
        add_count = 0
        add_next_p = P[start_p]
        while True:
            add_total_score += C[add_next_p]
            add_score = max(add_score, add_total_score)
            add_count += 1

            if add_count == add_max_count:
                break
            add_next_p = P[add_next_p]

        if K < cycle_count:
            #最大の試行回数がcycle_countよりも小さい場合K % cycle_countまでで一番良いところでbeak
            max_score = add_total_score
        else:
            if cycle_total_score >= 0:
                #1サイクルでプラスの場合はできるだけサイクルを回してK % cycle_countまでで一番良いところでbeak
                max_score = (K // cycle_count) * cycle_total_score + add_total_score
            else:
                #1サイクルでマイナスの場合はサイクルを回さないで、K % cycle_countまでで一番良いところでbreak
                max_score = add_total_score
    # print('max_score', max_score)
    answer = max(answer, max_score)

print(answer)

Submission status: Time Limit Exceeded

Solution code:
import sys
import numpy as np
# from numba import njit

# @njit(cache=True)
def calcCycle(N,K,P,C,cycleIDs,cycleItemCnts,cycleTotalScores):
	cycleID = 0

	for n in range(N):

		v = n
		currentCycleItemCnt = 0
		currentCycleTotal = 0

		if cycleIDs[v] != -1:
			continue
			# print(currentCycleItemCnt, currentCycleTotal)
		else:
			while True:
				# 全頂点について、属するサイクルを計算する
				currentCycleItemCnt += 1
				currentCycleTotal += C[v]

				v = P[v]
				if v == n:
					# サイクル発見
					cycleIDs[v] = cycleID
					cycleItemCnts[cycleID] = currentCycleItemCnt
					cycleTotalScores[cycleID] = currentCycleTotal
					cycleID += 1
					break

				# 一応、一度サイクルを計算した頂点については、
				# その頂点の属するサイクルの情報をメモっておく。。。
				cycleIDs[v] = cycleID

def upd(procCnt,P,C,K,v,ans,currentCycleSumTmp,currentCycleItemCnt,currentCycleTotal):
	currentCycleSumTmp += C[v]

	cycleLoopCnt = 0
	if 0 < currentCycleTotal:
		cycleLoopCnt = ( K - procCnt ) // currentCycleItemCnt

	# print("v=", v, "currentCycleSumTmp=", currentCycleSumTmp, "procCnt, cycleLoopCnt, currentCycleTotal=", procCnt, cycleLoopCnt, currentCycleTotal)
	ans = max( ans, currentCycleSumTmp + cycleLoopCnt * currentCycleTotal )
	v = P[v]

	return (currentCycleSumTmp, ans, v)




def main(N,K,P,C,cycleIDs,cycleItemCnts,cycleTotalScores):

	ans = -1e18

	for n in range(N):

		v = n
		currentCycleItemCnt, currentCycleTotal = cycleItemCnts[ cycleIDs[v] ], cycleTotalScores[ cycleIDs[v] ]

		# procCnt = 0
		currentCycleSumTmp = 0


		for k in range(min(K,currentCycleItemCnt)):
			# 頂点vにコマが置かれた時の最高スコアを計算し、
			# これまでの最高スコアを上回ったら、これまでの最高スコアを更新する
			currentCycleSumTmp, ans, v = upd(k+1,P,C,K,v,ans,currentCycleSumTmp,currentCycleItemCnt,currentCycleTotal)
			# procCnt = k+1
			# currentCycleSumTmp += C[v]

			# cycleLoopCnt = 0
			# if 0 < currentCycleTotal:
			# 	cycleLoopCnt = ( K - procCnt ) // currentCycleItemCnt

			# # print("v=", v, "currentCycleSumTmp=", currentCycleSumTmp, "procCnt, cycleLoopCnt, currentCycleTotal=", procCnt, cycleLoopCnt, currentCycleTotal)
			# ans = max( ans, currentCycleSumTmp + cycleLoopCnt * currentCycleTotal )
			# v = P[v]

	print(int(ans))

if sys.argv[-1]=='ONLINE_JUDGE':
	# from numba import njit
	from numba.pycc import CC
	cc=CC('my_module')
	cc.export('calcCycle','void(i8,i8,i8[:],i8[:],i8[:],i8[:],i8[:])')(calcCycle)
	# cc.export('main','void(i8,i8,i8[:],i8[:],i8[:],i8[:],i8[:])')(main)
	cc.export('upd','UniTuple(i8,3)(i8,i8[:],i8[:],i8,i8,i8,i8,i8,i8)')(upd)
	# main=njit(main, cache=True)
	cc.compile()
	exit(0)
from my_module import upd,calcCycle
# from my_module import calcCycle



if __name__ == "__main__":
	N,K = map(int,input().split())
	P = np.array( input().split(), np.int64 )
	P -= 1
	C = np.array( input().split(), np.int64 )

	# 一度計算したサイクル情報を一応キャッシュしておく。。。
	# あんまり意味なさそう
	cycleIDs = np.full( N, -1, dtype=np.int64 )
	cycleItemCnts = np.full( N, -1, dtype=np.int64 )
	cycleTotalScores = np.full( N, -1, dtype=np.int64 )

	calcCycle(N,K,P,C,cycleIDs,cycleItemCnts,cycleTotalScores)

	# print(cycleItemCnts)


	main(N,K,P,C,cycleIDs,cycleItemCnts,cycleTotalScores)
	#print(ans)

Submission status: Time Limit Exceeded

Solution code:
n, k = map(int, input().split())
p = list(map(int, input().split()))
c = list(map(int, input().split()))

lastans = -1e20

for i in range(n):
    now = p[i] - 1 
    score = [c[now]]
    while True:
        now = p[now] - 1
        score.append(score[-1] + c[now])
        if now == i:
            break
    loopsum = score[-1]
    looplen = len(score)
#    print(score)
    if looplen >= k:
        ans = max(score[:k])
    elif loopsum <= 0:
        ans = max(score)
    else:
        loopnum = k//looplen
        loopnum_mod = k % looplen
        ans1 = loopsum * (loopnum - 1) + max(score)
        ans2 = loopsum * loopnum
        if loopnum_mod != 0:
            ans2 = ans2 +max(0,max(score[:loopnum_mod]))
        ans =max(ans1,ans2)
    lastans = max(lastans,ans)

print(lastans)

Submission status: Time Limit Exceeded

Solution code:
'''
参考
https://marco-note.net/abc-175-work-log/
'''
N, K = map(int, input().split())        # コマ数、最大移動可能回数
P = list(map(int, input().split()))     # 移動先のコマ番号
C = list(map(int, input().split()))     # そのコマに立ち寄った時に加算される得点

ans = -float('inf')             # 解を-∞で初期化

for piece in range(N):          # 各コマについて、スタート地点とした場合の得点を調べる
    S = []                      # 累積和
    mov = P[piece] - 1          # 1回目の移動：移動先（indexなので-1する）
    S.append(C[mov])            # 1回目の移動：得点

    while mov != piece:             # 2回目以降の移動（スタート地点に戻ったらループ終了）
        mov = P[mov] - 1            # 2回目以降：移動先
        S.append(S[-1] + C[mov])    # 2回目以降：得点（最終要素に加算した値をリストに追加）
    
    if K <= len(S):             # 【パターン1】与えられた移動可能回数では一巡できない
        score = max(S[:K])      # 得点=移動可能回数までの最大得点
    elif S[-1] <= 0:            # 【パターン2】一巡できるが一巡してしまうと得点が減る
        score = max(S)          # 得点=一巡するまでの最大得点
    else:
        score_a = S[-1] * (K // len(S))     # 【パターン3-1】与えられた移動可能回数で廻れるだけ廻る
        rem = K % len(S)
        if rem != 0:
            score_a += max(0, max(S[:rem]))
        score_b = S[-1] * (K // len(S) - 1) # 【パターン3-2】1周少なく廻りあとは最高得点のところで止める
        score_b += max(S)
        score = max(score_a, score_b)
    
    ans = max(ans, score)

print(ans)