Prof. Santiago Valdés Ravelo santiago.ravelo@inf.ufrgs.br
Combinatória e teoria dos
números
Desafios de programação.
06
Outubro, 2020
requiring combinatorial thinking, react with one of two stock phrases: (a) “This is a purely combinatorial argument,” (b) “This is a difficult combinatorial argument.” Hypnotic repetition of either of these slogans is likely to have the same balming effect on the speaker: freed from all scruples, he will pass the buck and unload the work onto someone else’s shoulders.”
Gian-Carlo Rota
2 Recorrências
3 Divisibilidade e números primos
4 Congruências e aritmética modular
Combinações
Contando possibilidades
Dados dois conjuntos finitos de elementos𝐴e𝐵:
▶ Soma. Existem|𝐴| + |𝐵|possibilidades de selecionar um elemento de 𝐴ou de𝐵.
▶ Produto. Existem|𝐴| × |𝐵|possibilidades de selecionar um elemento de𝐴 e um elemento de𝐵.
Princípio de inclusão exclusão(generaliza a soma). Se𝐴e𝐵não são disjuntos, então existem|𝐴 ∪ 𝐵| = |𝐴| + |𝐵| − |𝐴 ∩ 𝐵|possibilidades de selecionar um elemento de𝐴ou de𝐵. Este princípio pode ser aplicado a mais conjuntos:
|𝐴 ∪ 𝐵 ∪ 𝐶| = |𝐴| + |𝐵| + |𝐶| − |𝐴 ∩ 𝐵| − |𝐴 ∩ 𝐶| − |𝐵 ∩ 𝐶| + |𝐴 ∩ 𝐵 ∩ 𝐶|
∣
𝑛
⋃
𝑖=1
𝐴𝑖∣ = ∑
𝑖=1
|𝐴𝑖| − ∑
1≤𝑖<𝑗≤𝑛
|𝐴𝑖∩ 𝐴𝑗| + ∑
1≤𝑖<𝑗<𝑘≤𝑛
|𝐴𝑖∩ 𝐴𝑗∩ 𝐴𝑘| − …
Contando possibilidades
Dado um conjunto finitos de𝑛elementos𝐴:
▶ Permutações. Existem 𝑛! possíveis permutações dos
elementos de𝐴. Onde uma permutação é uma sequência em que cada elemento aparece exatamente uma vez.
▶ Sequências. Existem 𝑛𝑚 possíveis sequências de tamanho𝑚 em que os elementos podem aparecer nenhuma ou mais de uma vez.
▶ Subconjuntos. Existem 2𝑛 possíveis subconjuntos de 𝐴.
Contando possibilidades
Dado um conjunto finitos de𝑛elementos𝐴: Coeficiente binomial. Existem ( 𝑛
𝑚 ) = 𝑛!
𝑚!×(𝑛−𝑚)! possíveis formas de selecionar𝑚elementos de 𝐴.
São os coeficientes que aparecem ao expandir(1 + 𝑥)𝑛:
(1 + 𝑥)𝑛= ( 𝑛
0 ) + ( 𝑛
1 ) × 𝑥 + ( 𝑛
2 ) × 𝑥2+ … + ( 𝑛
𝑖 ) × 𝑥𝑖+ … + ( 𝑛 𝑛 ) × 𝑥𝑛
De forma geral(𝑥 + 𝑦)𝑛= ∑𝑛𝑖=0( 𝑛
𝑖 ) × 𝑥𝑖× 𝑦𝑛−𝑖.
Coeficientes binomiais e triângulo de Pascal
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1 → coeficientes para 𝑛 = 4
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
…
Propriedades dos coeficientes binomiais
▶ ( 𝑛
𝑖 ) = ( 𝑛 𝑛 − 𝑖 ).
▶ ( 𝑛
𝑖 ) + ( 𝑛
𝑖 + 1 ) = ( 𝑛 + 1 𝑖 + 1 ).
▶ 2𝑛 = ∑𝑛𝑖=0( 𝑛 𝑖 ).
▶ 𝑛 × 2𝑛−1= ∑𝑛𝑖=0𝑖 × ( 𝑛 𝑖 ).
Recorrências
Contando com recorrências
Em alguns problemas é mais fácil contar as possibilidades usando recorrências.
Exemplo. Considere que desejamos cobrir uma área retangular de2 × 𝑛 𝑐𝑚2 com peças de2 × 1 𝑐𝑚2. De quantas formas pode ser coberta a mesa se as peças se podem rotar?
Há duas possibilidades para o começo:
⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟
subproblema com área2×(𝑛−1) 𝑐𝑚2
⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟
subproblema com área2×(𝑛−2) 𝑐𝑚2 Se𝑇𝑛denota o número de possibilidades, então:
𝑇𝑛=
⎧{
⎨{
⎩
1, 𝑛 = 1 2, 𝑛 = 2
𝑇𝑛−1+ 𝑇𝑛−2, 𝑛 > 2
Recorrências lineares
Recorrências lineares são da forma:
𝑇𝑛 = { 𝑏𝑛, 𝑛 ≤ 𝑘
∑𝑘𝑖=1𝑎𝑖× 𝑇𝑛−𝑖, 𝑛 > 𝑘
Onde𝑘, cada 𝑎𝑖 e cada 𝑏𝑖, são constantes. Muitas destas recorrências podem ser solucionadas como séries geométricas:
𝑇𝑛= 𝑐 × 𝑥𝑛, onde:
𝑇𝑛 = 𝑎1× 𝑇𝑛−1+ 𝑎2× 𝑇𝑛−2+ … + 𝑎𝑘× 𝑇𝑛−𝑘
⇒ 𝑐 × 𝑥𝑛= 𝑎1× 𝑐 × 𝑥𝑛−1+ 𝑎2× 𝑐 × 𝑥𝑛−2+ … + 𝑎𝑘× 𝑐 × 𝑥𝑛−𝑘
⇒ 𝑥⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟⏟𝑘− 𝑎1× 𝑥𝑘−1− 𝑎2× 𝑥𝑘−2− … − 𝑎𝑘
polinômio característico
= 0
Solucionando recorrências lineares
Dada a recorrência𝑇𝑛= { 𝑏𝑛, 𝑛 ≤ 𝑘
∑𝑘𝑖=1𝑎𝑖× 𝑇𝑛−𝑖, 𝑛 > 𝑘 .
▶ Obter o polinômio característico:
𝑝(𝑥) = 𝑥𝑘− 𝑎1× 𝑥𝑘−1− 𝑎2× 𝑥𝑘−2− … − 𝑎𝑘.
▶ Encontrar as raízes de𝑝(𝑥), isto é encontrar as soluções𝑥1,𝑥2,…𝑥𝑚 para as quais𝑝(𝑥) = 0.
▶ Se não existem raízes múltiplas, então𝑚 = 𝑘e:
𝑇𝑛= 𝑐1× 𝑥𝑛1 + 𝑐2× 𝑥𝑛2+ … + 𝑐𝑘× 𝑥𝑛𝑘= ∑𝑘𝑖=1𝑐𝑖× 𝑥𝑛𝑖.
▶ Caso contrário, se a multiplicidade da raiz𝑥𝑖é𝑟𝑖, então:
𝑇𝑛= ∑𝑚𝑖=1∑𝑟𝑗=0𝑖−1𝑐𝑖𝑗× 𝑛𝑗× 𝑥𝑗𝑖.
▶ Em qualquer caso, calcular os coeficientes𝑐, usando os𝑏𝑖valores iniciais.
Recorrências lineares. Cobrindo área retangular
No exemplo a recorrência foi𝑇𝑛=
⎧{
⎨{
⎩
1, 𝑛 = 1 2, 𝑛 = 2
𝑇𝑛−1+ 𝑇𝑛−2, 𝑛 > 2 .
O polinômio característico é𝑝(𝑥) = 𝑥2− 𝑥 − 1. As raízes do polinômio são𝑥1,2= 1±
√5 2 . Logo,𝑇𝑛= 𝑐1× (1+
√5
2 )𝑛+ 𝑐2× (1−
√5 2 )𝑛e:
𝑇1= 1 = 𝑐1× (1 +√ 5
2 )
1
+ 𝑐2× (1 −√ 5
2 )
1
𝑇2= 2 = 𝑐1× (1 +√ 5
2 )
2
+ 𝑐2× (1 −√ 5
2 )
2
Solucionando o sistema: 𝑐1= 3+
√5 5+√
5 e𝑐2= 3−
√5 5−√
5.
Recorrências lineares. Fibonacci
A sequência de Fibonacci é𝐹𝑛=
⎧{
⎨{
⎩
1, 𝑛 = 1 1, 𝑛 = 2
𝐹𝑛−1+ 𝐹𝑛−2, 𝑛 > 2 .
Semelhante à anterior, logo:𝐹𝑛= 𝑐1× (1+
√5
2 )𝑛+ 𝑐2× (1−
√5 2 )𝑛e:
𝑇1= 1 = 𝑐1× (1 +√ 5
2 )
1
+ 𝑐2× (1 −√ 5
2 )
1
𝑇2= 1 = 𝑐1× (1 +√ 5
2 )
2
+ 𝑐2× (1 −√ 5
2 )
2
Resultando em: 𝑐1= √1
5,𝑐2= −√1
5 e𝐹𝑛= √1
5× ((1+
√5
2 )𝑛− (1−
√5 2 )𝑛). Como0 < ∣1−
√5
2 ∣ < 1e decresce rapidamente quando𝑛 → ∞, temos que𝐹𝑛 pode ser estimada usando somente𝜙 = 1+
√5
2 (𝐹𝑛≈ [𝜙√𝑛
5]).
Contando com recorrências
Exemplo. Considere que desejamos escrever uma expressão com parêntesis abertos e fechados. Este tipo de expressão é válida se cada parêntese aberto tem um que fecha depois e se para cada fechado tem um aberto antes.
De quantas formas podemos escrever expressões válidas com𝑛pares de parêntesis?
Para o primeiro parêntese aberto, temo a seguintes opções
▶ Fechamos imediatamente depois (sem abrir mais parêntesis aninhados), resultando no subproblema com 𝑛 − 1pares de parêntesis.
▶ Permitimos abrir um parêntese aninhado e fechamos depois, resultando nos subproblemas com1par de parêntesis e com𝑛 − 2pares de parêntesis.
▶ …
▶ Permitimos abrir𝑖parêntesis antes de fechar o primeiro, resultando nos subproblemas com𝑖pares de parêntesis e com𝑛 − 𝑖 − 1pares de parêntesis. Observar que por cada possibilidade do primeiro subproblema temos uma do segundo.
▶ …
▶ Permitimos abrir todos os parêntesis antes de fechar o primeiro, resultando no subproblema com𝑛 − 1 pares de parêntesis.
Se𝑇𝑛denota o número de possibilidades, então considerando𝑇0= 1:
𝑇𝑛= 𝑇0× 𝑇𝑛−1+ 𝑇1× 𝑇𝑛−2+ … + 𝑇𝑛−1× 𝑇0= ∑𝑛−1𝑖=0𝑇𝑖× 𝑇𝑛−𝑖−1
Números de Catalan
Números de Catalansão definidos pela seguinte recorrência:
𝐶𝑛 = 𝐶0× 𝐶𝑛−1+ 𝐶1× 𝐶𝑛−2+ … + 𝐶𝑛−1× 𝐶0=
𝑛−1
∑
𝑖=0
𝐶𝑖× 𝐶𝑛−𝑖−1
Onde,𝐶0= 1.
Estes números podem ser calculado como:
𝐶𝑛= 1
𝑛 + 1( 2 × 𝑛
𝑛 )
Divisibilidade e
números primos
Divisibilidade
Definição. Dados dois inteiros 𝑚e 𝑛, é dito que𝑚 divide 𝑛se e somente se existe um inteiro𝑘tal que 𝑛 = 𝑚 × 𝑘. Nesses casos𝑛 émúltiplode 𝑚e que 𝑚 édivisor 𝑛.
Encontrando todos os divisores
Dado um inteiro𝑛 > 0como encontrar todos seus divisores?
Se𝑚 é divisor de 𝑛então1 ≤ 𝑚 ≤ 𝑛.
Todo divisor𝑚 ≥√
𝑛, deve ser multiplicado por𝑘 ≤√ 𝑛, para 𝑛 = 𝑚 × 𝑘.
É suficiente percorrer os números entre1e √ 𝑛!!
Encontrando todos os divisores
1 voiddivisores(intn) {
2 // verifica cada possível divisor
3 for(intk=1;k*k<=n;k++) {
4 // verifica se o número atual for divisor
5 if(n%k==0) {
6 cout<<"divisor: "<<k<<endl;
7 // se for menor que a raiz, então há outro divisor m = n / k
8 if(k*k<n)
9 cout<<"divisor: "<<n/k<<endl;
10 }
11 }
12 }
Máximo divisor comum (MDC)
Dados dois inteiros𝑚 e𝑛 como encontrar o máximo inteiro𝑑que é divisor de𝑚 e 𝑛?
Sempre existem dois inteiros𝑞 e0 ≤ 𝑟 < 𝑚 tais que 𝑛 = 𝑚 × 𝑞 + 𝑟 ⇒ 𝑟 = 𝑛 − 𝑚 × 𝑞.
Se𝑑é divisor de 𝑚 e 𝑛, então 𝑑é divisor de 𝑟.
Método de Euclides. O máximo divisor entre𝑚 e 𝑛é igual ao máximo divisor comum entre𝑚e 𝑟.
Máximo divisor comum (MDC)
1 intmdc(intm,intn) {
2 // se m for 0, n é divisor de m e dele mesmo
3 if(m==0)
4 returnn;
5 // caso contrário, método de Euclides
6 returnmdc(n%m,m);
7 }
Mínimo múltiplo comum (MMC)
Dados dois inteiros𝑚 e𝑛 como encontrar o mínimo inteiro𝑘 > 0 que é múltiplo de𝑚 e 𝑛?
Se𝑑é divisor de 𝑚 e 𝑛, então 𝑚×𝑛𝑑 é múltiplo de𝑚 e 𝑛.
O mínimo múltiplo comum de𝑚e 𝑛é igual a 𝑚𝑑𝑐(𝑚,𝑛)𝑚×𝑛 !!
Números primos
Definição. Um número inteiro 𝑝 > 1 é primo se e somente se os únicos divisores de𝑝 são 1e ele próprio.
Teorema Fundamental da Aritmética. Todo inteiro𝑛 > 1 se pode expressar de forma única como produto de fatores primos:
𝑛 = 𝑝𝑒11× 𝑝2𝑒1× … × 𝑝𝑘𝑒𝑘
Teorema. Existem infinitos números primos.
Teste de primalidade
Dado um inteiro𝑛como saber se ele é um número primo?
Verificar que não possui divisores diferente de1 e ele próprio!!
É suficiente testar os números entre2 e√ 𝑛.
Teste de primalidade
1 boolprimo(intn) {
2 // verifica cada valor a partir de 2 até raiz de n
3 for(inti=2;i*i<=n;i++) {
4 // se o número atual for divisor, então n não é primo
5 if(n%i==0)
6 returnfalse;
7 }
8 // se passou o teste, n é primo se for maior que 1
9 returnn>1;
10 }
Decomposição em fatores primos
Dado um inteiro𝑛como obter a sua decomposição em fator primos?
Verificar cada primo menor que ele e se for divisor do número imprimir o primo e a potência (número de vezes que o número pode ser divido pelo primo)!!
Para evitar testar se cada divisor é primo, assim que encontrado um divisor, atualizar o número dividindo-o pelo divisor tantas vezes quanto possível!
Decomposição em fatores primos
1 voidfatoracao(intn) {
2 // verifica cada possível fator
3 for(inti=2;i*i<=n;i++) {
4 // se o número atual for divisor, então é um fator primo
5 if(n%i==0) {
6 // inicializa a potencia desse fator
7 inte=0;
8 while(n%i== 0) {
9 e++;//incrementa a potência
10 n/=i;// divide o número pelo fator
11 }
12 cout<<"fator: "<<i<<" potencia: "<<e<<endl;
13 }
14 }
15 // verifica se o número é maior que 1, caso seja ele próprio é um fator primo
16 if(n>1)
17 cout<< "fator: "<<n<<" potencia: "<<1<< endl;
18 }
Encontrando o 𝑛-ésimo primo
Dado um inteiro𝑛como obter o 𝑛-ésimo primo?
Gerar todos os primos anteriores!!
Se um número é composto ele tem fatores primos menores, logo só é necessário testar os primos encontrados previamente.
Encontrando o 𝑛-ésimo primo
1 #define MAX 1000
23 intprimos[1000];
45 intn_primo(intn) {
6 //O primeiro número primo é o 2 e também é o único primo par
7 primos[0]=2;
8 // verifica cada possível número primo p, e posição i até n
9 // como os primos maiores que 2, são impares o incremento pode ser de 2 em 2
10 for(inti=1,p=3;i<n;p+=2) {
11 // verifica se o p atual é primo
12 boolprimo=true;
13 // analisa os primos anteriores
14 for(intj=0;j<i&&primos[j]*primos[j]<=p;j++) {
15 // se o p é dividido por algum primo, então não é primo
16 if(p%primos[j]== 0) {
17 primo=false;
18 break;
19 }
20 }
21 // se for primo o coloca no vetor
22 if(primo) {
23 primos[i]=p;
24 i++;
25 }
26 }
27 // retorna o ultimo primo encontrado
28 returnprimos[n-1];
29 }
Congruências e
aritmética modular
think of it as clock arithmetic. Temporarily replace the 12 on a clock face with 0. The 12 hours of the clock now read 0, 1, 2, 3, … up to 11. If the time is eight o’clock, and you add 9 hours, what do you get? Well, you get five o’clock. So in this arithmetic, 8 + 9
= 5; or, as mathematicians say, 8 + 9≡ 5 (mod 12), pronounced
’eight plus nine is congruent to five, modulo twelve’.”
John Derbyshire
Congruências
Dados os inteiros𝑛 > 0,𝑎e𝑏, dizemos que𝑎é congruente com 𝑏 modulo𝑛(𝑎 ≡ 𝑏 (𝑚𝑜𝑑 𝑛)) se𝑛é divisor de𝑎 − 𝑏.
A relação de congruência𝑎 ≡ 𝑏 (𝑚𝑜𝑑 𝑛) pode ser vista como uma igualdade no resto da divisão de𝑎por𝑛com o resto da divisão de𝑏por𝑛 Relações de congruência são equivalências. Para quaisquer inteiros 𝑛 > 0,𝑎,𝑏e𝑐:
▶ Reflexiva. 𝑎 ≡ 𝑎 (𝑚𝑜𝑑 𝑛).
▶ Simétrica. 𝑎 ≡ 𝑏 (𝑚𝑜𝑑 𝑛) ⇔ 𝑏 ≡ 𝑎 (𝑚𝑜𝑑 𝑛).
▶ Transitiva. 𝑎 ≡ 𝑏 (𝑚𝑜𝑑 𝑛), 𝑏 ≡ 𝑐 (𝑚𝑜𝑑 𝑛) ⇒ 𝑎 ≡ 𝑐 (𝑚𝑜𝑑 𝑛).
Aritmética modular. Adição / subtração
Para quaisquer inteiros𝑛 > 0,𝑎,𝑏,𝑐 e 𝑑:
Se𝑎 ≡ 𝑏 (𝑚𝑜𝑑 𝑛) e𝑐 ≡ 𝑑 (𝑚𝑜𝑑 𝑛), então𝑎 + 𝑐 ≡ 𝑏 + 𝑑 (𝑚𝑜𝑑 𝑛).
Algumas propriedades interessantes são:
▶ Se 𝑎 + 𝑏 = 𝑐, então𝑎 (𝑚𝑜𝑑 𝑛) + 𝑏 (𝑚𝑜𝑑 𝑛) ≡ 𝑐 (𝑚𝑜𝑑 𝑛).
▶ Se 𝑎 ≡ 𝑏 (𝑚𝑜𝑑 𝑛), então𝑎 + 𝑐 ≡ 𝑏 + 𝑐 (𝑚𝑜𝑑 𝑛).
Aritmética modular. Multiplicação
Para quaisquer inteiros𝑛 > 0,𝑎,𝑏,𝑐 e 𝑑:
Se𝑎 ≡ 𝑏 (𝑚𝑜𝑑 𝑛) e𝑐 ≡ 𝑑 (𝑚𝑜𝑑 𝑛), então𝑎 × 𝑐 ≡ 𝑏 × 𝑑 (𝑚𝑜𝑑 𝑛).
Algumas propriedades interessantes são:
▶ Se 𝑎 × 𝑏 = 𝑐, então𝑎 (𝑚𝑜𝑑 𝑛) × 𝑏 (𝑚𝑜𝑑 𝑛) ≡ 𝑐 (𝑚𝑜𝑑 𝑛).
▶ Se 𝑎 ≡ 𝑏 (𝑚𝑜𝑑 𝑛), então𝑎 × 𝑐 ≡ 𝑏 × 𝑐 (𝑚𝑜𝑑 𝑛).
▶ Se 𝑎 ≡ 𝑏 (𝑚𝑜𝑑 𝑛), então−𝑎 ≡ −𝑏 (𝑚𝑜𝑑 𝑛).
Aritmética modular. Multiplicação
Exemplo. Encontrar o resto da divisão de
102004 × 13000 × 5003 × 4208 × 532 × 13por 3.
102004×13000×5003×4208×532×13 ≡ 1×1×2×2×1×1 (𝑚𝑜𝑑 3).
1 × 1 × 2 × 2 × 1 × 1 = 4 ≡ 1 (𝑚𝑜𝑑 3).
Aritmética modular. Potenciação
Para quaisquer inteiros𝑘 > 0,𝑛 > 0,𝑎e𝑏:
Se𝑎 ≡ 𝑏 (𝑚𝑜𝑑 𝑛), então𝑎𝑘≡ 𝑏𝑘 (𝑚𝑜𝑑 𝑛).
Aritmética modular. Potenciação
Exemplo. Encontrar o resto da divisão de 31024 por 4.
32= 9 ≡ 1 (𝑚𝑜𝑑 4).
31024= (32)512≡ 1512(𝑚𝑜𝑑 4) ≡ 1 (𝑚𝑜𝑑 4).
Aritmética modular. Divisão
Em geral não é certo que se𝑎 ≡ 𝑏 (𝑚𝑜𝑑 𝑛) e𝑐 é divisor comum de 𝑎e𝑏 então 𝑎𝑐 ≡ 𝑏
𝑐 (𝑚𝑜𝑑 𝑛).
Exemplo. 9 ≡ 27 (𝑚𝑜𝑑 9) mas3 ≢ 9 (𝑚𝑜𝑑 9).
Para quaisquer inteiros𝑛 > 0,𝑎,𝑏 e 𝑐:
Se𝑎 × 𝑐 ≡ 𝑏 × 𝑐 (𝑚𝑜𝑑 𝑛) e𝑚𝑑𝑐(𝑐, 𝑛) = 1, então𝑎 ≡ 𝑏 (𝑚𝑜𝑑 𝑛).
Inverso multiplicativo
Para quaisquer inteiros𝑛 > 0e 𝑎:
Se𝑚𝑑𝑐(𝑎, 𝑛) = 1, então existe um inteiro𝑥 tal que 𝑎 × 𝑥 ≡ 1 (𝑚𝑜𝑑 𝑛).
Nesses casos𝑥 é oinverso multiplicativo de 𝑎 modulo 𝑛e se denota por𝑎−1.
Cálculo do inverso multiplicativo
Dados os inteiros𝑛 > 0 e𝑎 com𝑚𝑑𝑐(𝑎, 𝑛) = 1, o inverso multiplicativo (𝑎−1) de𝑎modulo𝑛 se obtém solucionando:
𝑎 × 𝑥 + 𝑛 × 𝑦 = 1
Onde𝑥 = 𝑎−1 e𝑦 são inteiros. Essa equação é um caso particular de:
𝑎 × 𝑥 + 𝑏 × 𝑦 = 𝑚𝑑𝑐(𝑎, 𝑏) Cuja solução pode ser escrita como𝑥 = 𝑦′− ⌊𝑏
𝑎⌋ × 𝑥′ e 𝑦 = 𝑥′, onde𝑥′e 𝑦′são solução de:
𝑏 (𝑚𝑜𝑑 𝑎) × 𝑥′+ 𝑎 × 𝑦′= 𝑚𝑑𝑐(𝑏 (𝑚𝑜𝑑 𝑎), 𝑎) = 𝑚𝑑𝑐(𝑎, 𝑏)
Algoritmo de Euclides estendido (e-MDC)
1 inte_mdc(inta,intb,int*x,int*y) {
2 // se a=0, então o máximo divisor comum é b e: b=a(x=0)+b(y=1)
3 if(a==0) {
4 *x=0;
5 *y=1;
6 returnb;
7 }
8 // caso contrário, método de Euclides
9 intx1,y1;// valores para x' e y'
10 intd=e_mdc(b%a,a,&x1,&y1); // chama recursivamente
11 // calcula o novo valor de x, a divisão entre inteiros (b / a) já garante o piso
12 *x=y1-(b/a)*x1;
13 *y=x1;// calcula o novo valor de y
14 returnd;
15 }
Congruências lineares
Dados os inteiros𝑛 > 0,𝑎e𝑏, se deseja encontrar um inteiro𝑥tal que:
𝑎 × 𝑥 ≡ 𝑏 (𝑚𝑜𝑑 𝑛)
Equivalente a solucionar𝑎 × 𝑥 + 𝑛 × 𝑦 = 𝑏, com𝑥e𝑦inteiros.
Temos então as seguintes possibilidades:
▶ Se𝑚𝑑𝑐(𝑎, 𝑛)não é divisor de𝑏, então a congruência não tem solução.
▶ Senão, a congruência tem solução onde:
▶ Se𝑚𝑑𝑐(𝑎, 𝑛) = 1, então existe uma única solução(𝑚𝑜𝑑 𝑛) (𝑥 = 𝑎−1× 𝑏).
▶ 𝑚𝑑𝑐(𝑎, 𝑛) > 1, então se podem dividir𝑎,𝑏e𝑛por𝑚𝑑𝑐(𝑎, 𝑛) e solucionar o novo problema.
Sistemas de congruências lineares
Dados os inteiros𝑛1, 𝑛2, … , 𝑛𝑚> 0e𝑎1, 𝑎2… , 𝑎𝑚, se deseja encontrar um inteiros𝑥tal que:
𝑥 ≡ 𝑎1 (𝑚𝑜𝑑 𝑛1) 𝑥 ≡ 𝑎2 (𝑚𝑜𝑑 𝑛2)
…
𝑥 ≡ 𝑎𝑚 (𝑚𝑜𝑑 𝑛𝑚)
Teorema chinês do resto. Se𝑚𝑑𝑐(𝑛𝑖, 𝑛𝑗) = 1para todo1 ≤ 𝑖 < 𝑗 ≤ 𝑚, então𝑥se determina univocamente(𝑚𝑜𝑑
𝑚
∏
𝑖=1
𝑛𝑖)pelo seguinte processo:
▶ Para cada1 ≤ 𝑖 ≤ 𝑚calcular𝑁𝑖= ∏
𝑗≠𝑖
𝑛𝑗.
▶ Para cada1 ≤ 𝑖 ≤ 𝑚solucionar𝑁𝑖× 𝑦𝑖≡ 1 (𝑚𝑜𝑑 𝑛𝑖).
▶ Solucionar𝑥 ≡
𝑚
∑
𝑖=1
𝑎𝑖× 𝑁𝑖× 𝑦𝑖(𝑚𝑜𝑑
𝑚
∏
𝑖=1
𝑛𝑖).
Prof. Santiago Valdés Ravelo santiago.ravelo@inf.ufrgs.br
Combinatória e teoria dos
números
Desafios de programação.
06
Outubro, 2020