// Cuenta cuántos elementos se trasladan al crecer, sin guardar ningún elemento:
// solo sigue el tamaño y la capacidad durante n inserciones.
#ifndef GROWTH_MATH_H
#define GROWTH_MATH_H

// next_capacity recibe la capacidad actual y devuelve la siguiente.
template <typename Next>
long long copies_for(long long n, Next next_capacity) {
    long long copies = 0;
    long long capacity = 0;
    for (long long size = 0; size < n; size++) {
        if (size == capacity) {
            copies += size;
            capacity = next_capacity(capacity);
        }
    }
    return copies;
}

inline long long copies_doubling(long long n) {
    return copies_for(n, [](long long c) { return c == 0 ? 1 : 2 * c; });
}

inline long long copies_step(long long n, long long k) {
    return copies_for(n, [k](long long c) { return c + k; });
}

// Multiplica por 3/2, redondeando hacia abajo, pero siempre crece al menos en 1.
inline long long copies_three_halves(long long n) {
    return copies_for(n, [](long long c) { return c < 2 ? c + 1 : c + c / 2; });
}

#endif
