Inversion.cpp 1.2 KB

1234567891011121314151617181920212223242526272829303132333435
  1. // Compte les inversions dans un tableau à l'aide du tri fusion
  2. // renvoie le nombre total, et rempli rep pour le nombre d'inversion comprenant
  3. // chaque élement (à droite) -> permet de compter le nombre de triplet inversion
  4. // COMPLEXITY: n log n
  5. // pair.first: valeur de la case
  6. // pair.second: indice dans le tableau initialement (rep est rempli en fonction)
  7. PII tmp[100001]; // tableau temporaire
  8. int rep[100001]; // réponse (doit être initialisé à 0)
  9. void fusion(PII *s1, PII *e1, PII *s2, PII *e2) {
  10. PII *start = s1, *end = e2;
  11. PII *p = tmp;
  12. while(s1 < e1 && s2 < e2) {
  13. if((inv && s2->first < s1->first) || (!inv && s2->first > s1->first)) {
  14. rep[s2->second] += e1-s1;
  15. *p = *s2; p++; s2++;
  16. }
  17. else
  18. *p = *s1; p++; s1++;
  19. }
  20. while(s1 < e1) *p = *s1; p++; s1++;
  21. while(s2 < e2) *p = *s2; p++; s2++;
  22. for(int i = 0; i < end-start; i++) // TODO memcpy ?
  23. start[i] = tmp[i];
  24. }
  25. // s: début du tableau (inclu), e: fin (exclu)
  26. int count_inv(PII *s, PII *e) {
  27. if(s == e)
  28. return;
  29. if(s + 1 == e)
  30. return;
  31. size_t seg = (e-s)/2;
  32. int rep = count_inv(s, s+seg) + count_inv(s+seg, e);
  33. rep += fusion(s, s+seg, s+seg, e);
  34. return rep;
  35. }