Inversion.cpp 1.2 KB

123456789101112131415161718192021222324252627282930313233343536
  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. typedef pair<int, int> PII;
  8. PII tmp[100001]; // tableau temporaire
  9. int rep[100001]; // réponse (doit être initialisé à 0)
  10. void fusion(PII *s1, PII *e1, PII *s2, PII *e2) {
  11. PII *start = s1, *end = e2;
  12. PII *p = tmp;
  13. while(s1 < e1 && s2 < e2) {
  14. if((inv && s2->first < s1->first) || (!inv && s2->first > s1->first)) {
  15. rep[s2->second] += e1-s1;
  16. *p = *s2; p++; s2++;
  17. }
  18. else
  19. *p = *s1; p++; s1++;
  20. }
  21. while(s1 < e1) *p = *s1; p++; s1++;
  22. while(s2 < e2) *p = *s2; p++; s2++;
  23. for(int i = 0; i < end-start; i++) // TODO memcpy ?
  24. start[i] = tmp[i];
  25. }
  26. // s: début du tableau (inclu), e: fin (exclu)
  27. int count_inv(PII *s, PII *e) {
  28. if(s == e)
  29. return;
  30. if(s + 1 == e)
  31. return;
  32. size_t seg = (e-s)/2;
  33. int rep = count_inv(s, s+seg) + count_inv(s+seg, e);
  34. rep += fusion(s, s+seg, s+seg, e);
  35. return rep;
  36. }