QOJ.ac

QOJ

Type: General Discussion

Status: Open

Posted by: N.Bahizi_Dylan

Posted at:

Last updated:

Back to Problem

New Editorial for Problem #15376

Approach: Binary Exponentiation

This solution uses Binary Exponentiation, an approach similar to Binary Lifting. Instead of storing all powers of two in a 2D array, we calculate the next power by squaring the current mapping.

Initially, p[i] represents the destination of person i after one step. By setting p[i] = p[p[i]], we double the number of steps represented by p.

We maintain another array, res, initialized so that res[i] = i. We process the binary representation of k from right to left. Whenever the current bit is set, we apply the current mapping to res. After each iteration, we square p and shift k one bit to the right.

After processing all bits, res[i] contains the final destination of the balls originally belonging to person i. We then add a[i] to ans[res[i]] and find the maximum number of balls.

The time complexity is 𝑂(𝑛logK) , while the auxiliary space complexity is 𝑂(𝑛) . Compared with traditional Binary Lifting, this approach is more memory-efficient because it does not store every power-of-two jump.

The original editorial for this problem, which uses traditional Binary Lifting, can be found on the COCI website.

Comments

avatar
N.Bahizi_Dylan
this is the code : #include <bits/stdc++.h> using namespace std; #define v vector #define pb push_back typedef long long ll; v<ll> app(v<ll>& p, ll k) { ll n = p.size(); v<ll> res(n); iota(res.begin(), res.end(), 0); while (k > 0) { if (k & 1) { v<ll> temp(n); for (int i = 0; i < n; i++) temp[i] = p[res[i]]; res = temp; } v<ll> temp(n); for (int i = 0; i < n; i++) temp[i] = p[p[i]]; p = temp; k >>= 1; } return res; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); ll n, k; cin >> n >> k; v<ll> a(n), crush(n); for (int i = 0; i < n; i++) cin >> a[i]; for (int i = 0; i < n; i++) { cin >> crush[i]; crush[i]--; } v<ll> ff = app(crush, k); v<ll> ans(n, 0); for (int i = 0; i < n; i++) ans[ff[i]] += a[i]; ll mx = *max_element(ans.begin(), ans.end()); cout << mx << '\n'; for (int i = 0; i < n; i++) { if (ans[i] == mx) cout << i + 1 << " "; } cout << '\n'; return 0; }