#include #include #define all(x) x.begin(), x.end() using namespace std; using namespace atcoder; using ll = long long; vector > convert_SCC_to_DAG(int n, vector& a, vector& b, vector >& route, vector >& scc) { int sz = scc.size(); vector p(sz), q(sz); vector > dag(sz, vector({})); vector group(n); for (int i = 0; i < sz; i++) { for (int x : scc[i]) { group[x] = i; p[i] += a[x]; q[i] += b[x]; } } a = p; b = q; for (int i = 0; i < n; i++) { for (int x : route[i]) { int a = group[i]; int b = group[x]; if (a != b) { dag[a].push_back(b); } } } for (vector& v : dag) { sort(all(v)); v.erase(unique(all(v)), v.end()); } return dag; } ll get_dp(ll mid, int n, vector& a, vector& b, vector >& dag, unordered_set& visited, int x) { visited.insert(x); ll ret = a[x] - b[x] * mid; for (int k : dag[x]) { ret += get_dp(mid, n, a, b, dag, visited, k); } return min(ret, 0ll); } bool check(ll mid, int n, vector& a, vector& b, vector >& dag) { unordered_set visited = {}; for (int i = 0; i < n; i++) { if (visited.find(i) != visited.end() or get_dp(mid, n, a, b, dag, visited, i) >= 0) { continue; } return false; } return true; } int main(void) { int n; cin >> n; vector a(n), b(n); vector c(n); ll sa = 0, sb = 0; for (int i = 0; i < n; i++) { cin >> a[i]; sa += a[i]; } for (int i = 0; i < n; i++) { cin >> b[i]; sb += b[i]; } for (int i = 0; i < n; i++) { cin >> c[i]; c[i]--; } vector > route(n, vector({})); scc_graph g(n); for (int i = 0; i < n; i++) { if (i == c[i]) { continue; } route[c[i]].push_back(i); g.add_edge(c[i], i); } vector > scc = g.scc(); vector > dag = convert_SCC_to_DAG(n, a, b, route, scc); n = scc.size(); ll ok = 0; ll ng = sa / sb + 1; while (ng - ok > 1) { ll mid = (ok + ng) >> 1ll; if (check(mid, n, a, b, dag)) { ok = mid; } else { ng = mid; } } cout << ok << endl; return 0; }