Sunteți pe pagina 1din 3

XOR:

Fie S(n)=1 xor 2 xor 3 xor xor n. Sa se calculeze S(n). Primul impuls este de a crea un algoritm care sa faca o parcurgere de la 1 la n. Acest lucru ar insemna foarte mult timp consumat (rezulta o complexitate O(n)). Voi incerca sa demonstrez ca se poate rezolva in O(1). Deducem ca: S(n)=n+1 cand (n+1) MOD 4=3 ; 1 cand (n+1) MOD 4=2; n cand (n+1) MOD 4=1; 0 cand (n+1) MOD 4=0. Demonstram prin inductie (ma voi folosi doar de pasul al doilea, nu e nevoie sa folosesc pasul 1 deoarece se calculeaza usor). S(n+1)=S(n) xor n+1 P(n): S(n)=n+1 cand (n+1) MOD 4=3 ; 1 cand (n+1) MOD 4=2; n cand (n+1) MOD 4=1; 0 cand (n+1) MOD 4=0. Trebuie sa demonstram ca: P(n+1): S(n+1)=n+2 cand (n+2) MOD 4=3 ; 1 cand (n+2) MOD 4=2; n+1 cand (n+2) MOD 4=1; 0 cand (n+2) MOD 4=0. I (n+1) MOD 4=3 deci rezulta ca S(n)=n+1 si (n+2) MOD 4=0 S(n+1)=S(n) xor n+1=n+1 xor n+1=0 II (n+1) MOD 4=2 deci rezulta ca S(n)=1 si (n+2) MOD 4=3 S(n+1)=S(n) xor n+1=1 xor n+1 n+1 este par din ipoteza Din reprezentarea binara rezulta: 0 0 0 0 1 xor a1 a2 ak-1 0=a1 a2 ak-1 1 Unde a1, a2, ak-1 apartin {0,1} a1 a2 ak-1 0 reprezinta numarul n+1 Deci S(n+1)=n+1 + 2^0=n+2 III (n+1) MOD 4=1 deci rezulta ca S(n)=n si (n+2) MOD 4=2 S(n+1)=S(n) xor n+1=n xor n+1 Stim din ipoteza ca n+1 e impar deci n e par. Reprezentand binar obtinem: a1 a2 ak-1 1 xor a1 a2 ak-1 0=1 Unde a1, a2, ak-1 apartin {0,1} Deci S(n+1)=1 IV (n+1) MOD 4=0 deci rezulta ca S(n)=0 si (n+2) MOD 4=1 S(n+1)=S(n) xor n+1=0 xor n+1=n+1 Deci P(n)=>P(n+1)

Am demonstrat ca: S(n)=n+1 cand (n+1) MOD 4=3 ; 1 cand (n+1) MOD 4=2; n cand (n+1) MOD 4=1; 0 cand (n+1) MOD 4=0. Implementare: Code: #include<stdio.h> int main() { int n; scanf("%d",&n); switch((n+1)%4) { case 0: printf("0"); break; case 1: printf("%d",n); break; case 2: printf("%d",1); break; case 3: printf("%d",n+1); break; } return 0; }

OR:
Fie R(n)=1 or 2 or 3 or or n, n>1 Sa se calculeze R(n). Vom rezolva in O(log N). R(n)=2^x-1, unde 2^x este cel mai mic numar mai mare ca n. Reprezentand binar, se observa ca facand operatia or intre numere consecutive exista tendinta de a se umple cu 1. Acest fapt rezulta in crearea rezultatului de mai sus. Stim ca R(n)=2^x-1. Demonstram ca R(2^x+1)=2^(x+1)-1. R(n): 0 1 1 1 R(2^x): 1 0 0 0 R(2^x+1)=R(n) or R(2^x)=1 1 1 1= 2^(x+1)-1 Deci am demonstrat ca: R(n)=2^x-1, unde 2^x este cel mai mic numar mai mare ca n.

Rezulta complexitate O(log N) deoarece putem aproxima numarul de cifre a lui n la 1. (vezi implementarea) Implementare: Code: #include<stdio.h> #include<math.h> int main() { int n; scanf("%d",&n); int c=0; while(n){n/=2; c++;} printf("%d",(int)pow(2,c)-1); return 0; }

AND:
Fie A(n)=1 and 2 and 3 and and n, n>1 Sa se calculeze A(n). Se deduce rapid ca A(n)=0. Implementare: Code: #include<stdio.h> #include<math.h> int main() { int n; scanf("%d",&n);//putem renunta la citire. printf("0"); return 0; }

BITWISE SHIFTS:
Bitwise Left Shift: x = a << b atunci x = a*2^b; Bitwise Right Shift: x = a >> b atunci x = a/2^b;

S-ar putea să vă placă și