Bots
Implementación
#include <cassert>
#include <iostream>
#include <vector>
const int MOD = 1e9 + 7;
long long pow(long long base, long long exp) {
assert(exp >= 0);
base %= MOD;
long long res = 1;
while (exp > 0) {
if (exp % 2 == 1) // si n es impar
res = res * base % MOD;
base = base * base % MOD;
exp /= 2;
}
return res;
}
long long mod_inv(long long n) { return pow(n, MOD - 2); }
int main() {
int max_moves;
std::cin >> max_moves;
long long total_states = 1;
long long curr_level = 1;
for (int l = 1; l <= max_moves; l++) {
curr_level = (curr_level * 2) % MOD;
total_states = (total_states + curr_level) % MOD;
}
// hay que multiplicar por 2 para obtener la cantidad real de vértices de un solo hijo
long long half_one_child_num = 1;
for (int l = max_moves + 1; l <= 2 * max_moves; l++) {
curr_level = (2 * curr_level - 2 * half_one_child_num) % MOD;
total_states = (total_states + curr_level) % MOD;
half_one_child_num = (half_one_child_num * l) % MOD;
half_one_child_num = (half_one_child_num * mod_inv(l - max_moves)) % MOD;
}
std::cout << (total_states + MOD) % MOD << std::endl;
}import java.io.*;
public class Bots {
private static final int MOD = (int)Math.pow(10, 9) + 7;
public static void main(String[] args) throws IOException {
int max_moves = Integer.parseInt(
new BufferedReader(new InputStreamReader(System.in)).readLine());
long total_states = 1;
long curr_level = 1;
for (int l = 1; l <= max_moves; l++) {
curr_level = (curr_level * 2) % MOD;
total_states = (total_states + curr_level) % MOD;
}
// hay que multiplicar por 2 para obtener la cantidad real de vértices de un solo hijo
long half_one_child_num = 1;
for (int l = max_moves + 1; l <= 2 * max_moves; l++) {
curr_level = (2 * curr_level - 2 * half_one_child_num) % MOD;
total_states = (total_states + curr_level) % MOD;
half_one_child_num = (half_one_child_num * l) % MOD;
half_one_child_num =
(half_one_child_num * modInv((long)l - max_moves)) % MOD;
}
System.out.println((total_states + MOD) % MOD);
}
private static long modInv(long n) { return pow(n, MOD - 2); }
private static long pow(long base, long exp) {
assert exp >= 0;
base %= MOD;
long res = 1;
while (exp > 0) {
if (exp % 2 == 1) // si n es impar
res = res * base % MOD;
base = base * base % MOD;
exp /= 2; // dividir por dos
}
return res;
}
}MOD = int(1e9) + 7
def mod_inv(n: int):
return pow(n, MOD - 2, MOD)
max_moves = int(input())
total_states = 1
curr_level = 1
for l in range(1, max_moves + 1):
curr_level = (curr_level * 2) % MOD
total_states = (total_states + curr_level) % MOD
# hay que multiplicar por 2 para obtener la cantidad real de vértices de un solo hijo
half_one_child_num = 1
for l in range(max_moves + 1, 2 * max_moves + 1):
curr_level = (2 * curr_level - 2 * half_one_child_num) % MOD
total_states = (total_states + curr_level) % MOD
half_one_child_num = (half_one_child_num * l * mod_inv(l - max_moves)) % MOD
print(total_states)Solución 2
Definamos primero una recurrencia de DP, con siendo la cantidad de estados únicos donde el bot azul hizo movimientos y el bot rojo hizo movimientos:
Se sigue que la respuesta es la suma de todos los elementos de .
Así se podría ver para :
| 1 | 1 | 1 | 1 | 1 |
| 1 | 2 | 3 | 4 | 5 |
| 1 | 3 | 6 | 10 | 15 |
| 1 | 4 | 10 | 20 | 35 |
| 1 | 5 | 15 | 35 | 70 |
Notar que estos números son exactamente los mismos que los del triángulo de Pascal, ¡solo que un poco rotados! Estos números forman un cuadrado rotado de longitud (de ahora en más ), y podemos expresar su suma como
Usando la identidad del palo de hockey , vemos que esto es igual a
También sabemos por la identidad del palo de hockey que . Así, obtenemos que
Implementación 2
Complejidad temporal:
#include <cassert>
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::pair;
const int MOD = 1e9 + 7;
long long pow(long long base, long long exp) {
assert(exp >= 0);
base %= MOD;
long long res = 1;
while (exp > 0) {
if (exp % 2 == 1) // si n es impar
res = res * base % MOD;
base = base * base % MOD;
exp /= 2;
}
return res;
}
long long mod_inv(long long n) { return pow(n, MOD - 2); }
int main() {
int max_moves;
std::cin >> max_moves;
pair<int, int> res_binom{max_moves * 2 + 2, max_moves + 1};
long long res_num = 1;
for (int i = res_binom.first; i > res_binom.first - res_binom.second; i--) {
res_num = res_num * i % MOD;
}
for (int i = 1; i <= res_binom.second; i++) {
res_num = res_num * mod_inv(i) % MOD;
}
cout << res_num - 1 << endl;
}import java.io.*;
public class Bots {
private static final int MOD = (int)Math.pow(10, 9) + 7;
public static void main(String[] args) throws IOException {
int maxMoves = Integer.parseInt(
new BufferedReader(new InputStreamReader(System.in)).readLine());
int[] resBinom = new int[] {2 * maxMoves + 2, maxMoves + 1};
long resNum = 1;
for (int i = resBinom[0]; i > resBinom[0] - resBinom[1]; i--) {
resNum = resNum * i % MOD;
}
for (int i = 1; i <= resBinom[1]; i++) { resNum = resNum * modInv(i) % MOD; }
System.out.println(resNum - 1);
}
private static long modInv(long n) { return pow(n, MOD - 2); }
private static long pow(long base, long exp) {
assert exp >= 0;
base %= MOD;
long res = 1;
while (exp > 0) {
if (exp % 2 == 1) // si n es impar
res = res * base % MOD;
base = base * base % MOD;
exp /= 2; // dividir por dos
}
return res;
}
}MOD = int(1e9) + 7
def mod_inv(n: int):
return pow(n, MOD - 2, MOD)
max_moves = int(input())
res_binom = [2 * max_moves + 2, max_moves + 1]
res_num = 1
for i in range(res_binom[0], res_binom[0] - res_binom[1], -1):
res_num = (res_num * i) % MOD
for i in range(1, res_binom[1] + 1):
res_num = (res_num * mod_inv(i)) % MOD
print(res_num - 1)