+/* Potenciacion usando división y conquista.
+ * Toma dos parametros u y v, devuelve u^v; asume v positivo.
+ *
+ * El pseudocódigo del algoritmo es:
+ * pot(x, y):
+ * if y == 1:
+ * return x
+ * res = pot(x, y/2)
+ * res = res * res
+ * if y es impar:
+ * res = res * x
+ * return res
+ *
+ * Es O(n) ya que la ecuación es T(n) = T(n/2) + O(1)
+ *
+ * El grafo que lo 'representa' (siendo los nodos el exponente y) algo como:
+ *
+ * 1 3
+ * _/ | \_
+ * _/ | \_
+ * / | \
+ * 6 1 6
+ * / \ / \
+ * / \ / \
+ * 3 3 3 3
+ * /|\ /|\ /|\ /|\
+ * 2 1 2 2 1 2 2 1 2 2 1 2
+ * / \ / \ / \ / \ / \ / \ / \ / \
+ * 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ *
+ */
+template < typename N, typename E >
+number< N, E > pot_dyc_n(const number< N, E > &x, const number< N, E > &y)
+{
+ assert(y.sign == positive);
+ if (y == number< N, E >(1))
+ {
+ return x;
+ }
+ number< N, E > res = pot_dyc_n(x, y.dividido_dos());
+ res = naif(res, res);
+ if (y.es_impar())
+ {
+ res = naif(res, x); // Multiplico por el x que falta
+ }
+ return res;
+}
+
+/* Idem que pot_dyc_n(), pero usa karatsuba() para las multiplicaciones. */
+template < typename N, typename E >
+number< N, E > pot_dyc_k(const number< N, E > &x, const number< N, E > &y)
+{
+ assert(y.sign == positive);
+ if (y == number< N, E >(1))
+ {
+ return x;
+ }
+ number< N, E > res = pot_dyc_k(x, y.dividido_dos());
+ res = karatsuba(res, res);
+ if (y.es_impar())
+ {
+ res = karatsuba(res, x);
+ }
+ return res;
+}
+