int n, k, ans(-1e18), cyBeg, cyEnd; array<int, MAXN> to, c, vis, pre, preMax; vector<int> node;
inlinevoiddfs(int cur){ vis[cur] = true; node.push_back(cur); if (vis[to[cur]]) { cyEnd = node.size() - 1; //环终点 for (int i = 0; i < node.size(); i++) if (node[i] == to[cur]) { cyBeg = i; //环起点 break; } } else dfs(to[cur]); }
inlinevoidsearch(int st){ node.clear(); fill(vis.begin(), vis.end(), 0); fill(pre.begin(), pre.end(), 0); fill(preMax.begin(), preMax.end(), -1e18); cyBeg = cyEnd = -1; dfs(st); for (int i = 1; i < node.size(); i++) pre[i] = pre[i - 1] + c[node[i]], preMax[i] = max(preMax[i - 1], pre[i]); ans = max(ans, preMax[min(k, (int)node.size() - 1)]); if (k <= cyEnd || cyBeg == - 1 || cyEnd == -1) return; if (cyBeg == 0) { //一开始就有环 int valC = pre[cyEnd] + c[node[cyBeg]]; if (valC < 0) return; int tim = k / node.size(), res = k % node.size(); ans = max(ans, tim * valC + max(0LL, preMax[res])); ans = max(ans, (tim - 1) * valC + max(0LL, preMax[cyEnd])); return; } int tmp = pre[cyBeg - 1]; fill(pre.begin(), pre.end(), 0); fill(preMax.begin(), preMax.end(), -1e18); int valC = 0, cSize = cyEnd - cyBeg + 1, tim, res; for (int i = cyBeg; i <= cyEnd; i++) { //环上前缀和 valC += c[node[i]]; pre[i] = pre[i - 1] + c[node[i]]; preMax[i] = max(preMax[i - 1], pre[i]); } if (valC < 0) return; k -= cyBeg - 1, tim = k / cSize, res = k % cSize; ans = max(ans, tmp + valC * tim + max(0LL, preMax[cyBeg + res - 1])); ans = max(ans, tmp + valC * (tim - 1) + max(0LL, preMax[cyEnd])); }
signedmain(){ std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cin >> n >> k; for (int i = 1; i <= n; i++) cin >> to[i]; for (int i = 1; i <= n; i++) cin >> c[i]; for (int i = 1; i <= n; i++) search(i); cout << ans << endl; return0; }