Advertisement
Guest User

Untitled

a guest
Nov 26th, 2014
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.90 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define FOR(i,a,b) for(__typeof(b) i=a; i<(b); ++i)
  3. #define FOR0(i,b) for(__typeof(b) i=0; i<(b); ++i)
  4. #define FOR1(i,b) for(__typeof(b) i=1; i<=(b); ++i)
  5. #define TRAV(it,c) for(__typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it)
  6. #define RTRAV(it,c) for(__typeof((c).rbegin()) it=(c).rbegin(); it!=(c).rend(); ++it)
  7. using namespace std;
  8. typedef pair<int, int> pii;
  9. typedef vector<int> vi;
  10. typedef vector<bool> vb;
  11. typedef vector<vb> vbb;
  12. typedef vector<vi> vii;
  13. typedef vector<pii> vpii;
  14. typedef long long ll;
  15.  
  16. #define N 1000000
  17. int v1[N+10];
  18. int v2[N+10];
  19. int v3[N+10];
  20. int v4[N+10];
  21. int v5[N+10];
  22. int v6[N+10];
  23. int v7[N+10];
  24. int n = N;
  25. bool swap_equal = true;
  26.  
  27. void insertion_sort(int v[], int n){
  28.     FOR(i, 1, n){
  29.         for(int j =i; j && v[j] < v[j-1]; --j) swap(v[j], v[j-1]);
  30.     }
  31. }
  32.  
  33. void Quicksort1(int v[], int n){   
  34.     if(n<=1) return;
  35.    
  36.     int p1 = rand()%n;  //escolhe um pivo aleatoriamente
  37.     swap(v[0],v[p1]);
  38.  
  39.     int l = 1;  // invariante: para todo x < i, v[x] < v[p]
  40.     FOR(j,1,n){
  41.          if( v[j] < v[0] ) swap(v[j], v[l++]);  // manuntencao da invariante
  42.          else if ( v[j] == v[0] ){  // quando o elemento for igual, alterna o lado no qual ele eh jogado para evitar a geracao de particoes desbalanceadas
  43.              if( swap_equal ) swap(v[j], v[l++]);
  44.              swap_equal = !swap_equal;
  45.         }
  46.     }
  47.  
  48.     swap(v[0], v[l-1]);
  49.     p1 = l-1;   //nova posicao do pivo
  50.  
  51.     Quicksort1(v, p1);  //orderna primeira metade
  52.     Quicksort1(v+p1+1, n - p1 - 1 ); //ordena segunda metade
  53. }
  54.  
  55. int auxpivots[10];
  56. void get_pivots(int v[], int n, int num_pivots){
  57.    
  58.     auxpivots[0] = rand()%n;
  59.     FOR(i,1,num_pivots*2 + 1){
  60.        
  61.         while( true ){
  62.             int next_pivot = rand()%n;
  63.             bool dif = true;
  64.             FOR0(j,i+1) if( next_pivot == auxpivots[j] ){
  65.                 dif = false;
  66.                 break;
  67.             }
  68.             if( dif ){
  69.                 auxpivots[i] = next_pivot;
  70.                 break;
  71.             }
  72.         }
  73.     }
  74.  
  75.     FOR(i, 1, num_pivots*2 + 1){
  76.         for(int j =i; j && v[  auxpivots[j] ] < v[  auxpivots[j-1] ]; --j) swap(auxpivots[j], auxpivots[j-1]);
  77.     }
  78.    
  79. }
  80.  
  81. void QuicksortH1(int v[], int n){
  82.    
  83.     if(n<=17){
  84.         insertion_sort(v,n);
  85.         return;
  86.     }
  87.  
  88.     get_pivots(v,n,1);
  89.     int p = auxpivots[1]; //escolhe pivot segundo criterio solicitado
  90.     swap(v[0],v[p]);
  91.  
  92.     int l = 1;  // invariante: para todo x < i, v[x] < v[p]
  93.     FOR(j,1,n){
  94.          if( v[j] < v[0] ) swap(v[j], v[l++]);  // manuntencao da invariante
  95.          else if ( v[j] == v[0] ){  // quando o elemento for igual, alterna o lado no qual ele eh jogado para evitar a geracao de particoes desbalanceadas
  96.              if( swap_equal ) swap(v[j], v[l++]);
  97.              swap_equal = !swap_equal;
  98.         }
  99.     }
  100.    
  101.     swap(v[0], v[l-1]);
  102.     p = l-1;    //nova posicao do pivo
  103.  
  104.     QuicksortH1(v, p);  //orderna primeira metade
  105.     QuicksortH1(v+p+1, n - p - 1 ); //ordena segunda metade
  106. }
  107.  
  108. int dual_pivotation(int v[], int n, int& l, int& r){
  109.    
  110.     if( v[0] > v[n-1] ) swap(v[0], v[n-1]);
  111.    
  112.     int vp1 = v[0];
  113.     int vp2 = v[n-1];
  114.    
  115.     //invariante: para todo x < l e y > r, v[x] < vp1 e v[y] > vp2
  116.     l = 1;
  117.     int i = 1;
  118.     r = n-2;
  119.    
  120.     while( i<=r ){
  121.         if( v[i] < vp1 ){   //manuntencao da invariante
  122.             swap( v[i++], v[l++] );
  123.         }
  124.         else if( v[i] > vp2 ){  //manuntencao da invariante
  125.             swap( v[i], v[r--] );
  126.         }
  127.         else{   //  vp1 <= v[i] <= vp2, apenas avance, invariante nao eh violada
  128.             ++i;
  129.         }
  130.     }
  131.  
  132.     swap(v[0], v[--l]);
  133.     swap( v[n-1], v[++r] );
  134. }
  135.  
  136. void Quicksort2(int v[], int n){   
  137.        
  138.     if(n<=1) return;
  139.    
  140.     int p1,p2;
  141.     dual_pivotation(v,n,p1,p2);
  142.    
  143.     Quicksort2(v, p1);  //ordena vetor com elementos cujos valores sao menor que o pivot 1
  144.     Quicksort2(v + p1 + 1, p2 - p1 - 1);    // ordenada valores entre p1 e p2, inclusive
  145.     Quicksort2(v+p2+1, n-p2-1); //ordena valores maiores que p2
  146. }
  147.  
  148. void QuicksortH2(int v[], int n){  
  149.        
  150.     if(n<=17){
  151.         insertion_sort(v,n);
  152.         return;
  153.     }
  154.    
  155.     int p1,p2;
  156.     get_pivots(v,n,2);
  157.     p1 = auxpivots[1];  //pivo 1
  158.     p2 = auxpivots[3];  // pivo 2
  159.     // v[p1] <= v[p2]
  160.    
  161.     //posiciona os pivos escolhidos nos extremos do vetor a fim de facilitar o pivoteamento
  162.     swap(v[0], v[p1]); 
  163.     swap(v[n-1], v[p2]);
  164.    
  165.     dual_pivotation(v,n,p1,p2);
  166.     //p1 e p2 agora possuem as novas posicoes dos pivos
  167.    
  168.     QuicksortH2(v, p1); //ordena vetor com elementos cujos valores sao menor que o pivot 1
  169.     QuicksortH2(v + p1 + 1, p2 - p1 - 1);   // ordenada valores entre p1 e p2, inclusive
  170.     QuicksortH2(v+p2+1, n-p2-1);    //ordena valores maiores que p2
  171. }
  172.  
  173. void triple_partition(int v[], int n, int& p1, int& p2, int& p3){
  174.     int a = 2;
  175.     int b = 2;
  176.     int c = n-2;
  177.     int d = n-2;
  178.     int p = v[0], q = v[1], r = v[n-1];
  179.     while( b<=c ){
  180.         while( v[b] < q && b <=c ){
  181.             if( v[b] < p ){
  182.                 swap(v[a], v[b]);
  183.                 ++a;
  184.             }
  185.             ++b;
  186.         }
  187.         while( v[c] > q && b <= c ){
  188.             if( v[c] > r ){
  189.                 swap(v[c], v[d]);
  190.                 --d;
  191.             }
  192.             --c;
  193.         }
  194.         if( b<= c ){
  195.             if( v[b] > r ){
  196.                 if( v[c] < p ){
  197.                     swap(v[b], v[a]);
  198.                     swap(v[a], v[c]);
  199.                     ++a;
  200.                 }
  201.                 else{
  202.                     swap(v[b], v[c]);
  203.                 }
  204.                 swap(v[c], v[d]);
  205.                 ++b;
  206.                 --c;
  207.                 --d;
  208.             }
  209.             else{
  210.                 if( v[c] < p ){
  211.                     swap(v[b], v[a]);
  212.                     swap(v[a], v[c]);
  213.                     ++a;
  214.                 }
  215.                 else{
  216.                     swap(v[b], v[c]);
  217.                 }
  218.                 ++b;
  219.                 --c;
  220.             }
  221.         }
  222.     }
  223.     --a;
  224.     --b;
  225.     ++c;
  226.     ++d;
  227.     swap(v[1], v[a]);
  228.     swap(v[a], v[b]);
  229.     p2 = b;
  230.     --a;
  231.     swap(v[0], v[a]);
  232.     p1 = a;
  233.     swap(v[n-1], v[d]);
  234.     p3 = d;
  235.    
  236. }
  237.  
  238. void Quicksort3(int v[], int n){
  239.    
  240.     if(n<=1) return;    // um vetor com um unico elemento ja esta ordenado, nao faca nada
  241.     if( n==2 ){
  242.         if( v[0] > v[1] ) swap(v[0], v[1]); // ordenacao de um vetor de 2 elementos eh trivial
  243.         return;
  244.     }
  245.    
  246.     //garantindo pivo1 <= pivo2 <= pivo3
  247.     if( v[0] > v[1] ) swap(v[0],v[1]);
  248.     if( v[1] > v[n-1] ) swap(v[1], v[n-1]);
  249.     if( v[0] > v[1] ) swap(v[0], v[1]);
  250.  
  251.     int p1,p2,p3;
  252.     triple_partition(v,n,p1,p2,p3);
  253.     //p1,p2,p3 agora possuem as novas posicoes dos pivos
  254.    
  255.     //ordena as quatro partes
  256.     Quicksort3(v,p1);
  257.     Quicksort3(v + p1 + 1 , p2 - p1 -1 );
  258.     Quicksort3(v + p2 + 1, p3 - p2 - 1 );
  259.     Quicksort3(v + p3 + 1, n - p3 -1 );
  260. }
  261.  
  262. void QuicksortH3(int v[], int n){
  263.    
  264.     if(n<=17){
  265.         insertion_sort(v,n);
  266.         return ;
  267.     }
  268.    
  269.     int p1,p2,p3;
  270.     get_pivots(v, n, 3);
  271.     p1 = auxpivots[1];  //pivo 1
  272.     p2 = auxpivots[3];  // pivo 2
  273.     p3 = auxpivots[5];  //pivo 3
  274.     //posiciona os pivos escolhidos nos extremos do vetor a fim de facilitar o pivoteamento
  275.     swap(v[0], v[p1]);
  276.     swap(v[1], v[p2]);
  277.     swap(v[n-1], v[p3]);
  278.    
  279.     //garantindo pivo1 <= pivo2 <= pivo3
  280.     if( v[0] > v[1] ) swap(v[0],v[1]);
  281.     if( v[1] > v[n-1] ) swap(v[1], v[n-1]);
  282.     if( v[0] > v[1] ) swap(v[0], v[1]);
  283.    
  284.     triple_partition(v,n,p1,p2,p3);
  285.     //p1,p2,p3 agora possuem as novas posicoes dos pivos
  286.    
  287.     //ordena as quatro partes
  288.     QuicksortH3(v,p1);
  289.     QuicksortH3(v + p1 + 1 , p2 - p1 -1 );
  290.     QuicksortH3(v + p2 + 1, p3 - p2 - 1 );
  291.     QuicksortH3(v + p3 + 1, n - p3 -1 );
  292. }
  293.  
  294. int main(){
  295.     srand( time(NULL) );
  296.    
  297.     FOR0(i,n) v1[i] = v2[i] = v3[i] = v4[i] = v5[i] = v6[i] = v7[i] = ( rand()%2000000000 * ( rand()%2 ? 1 : -1 ) );
  298.        
  299.     ll a = clock();
  300.     sort(v1,v1+n);
  301.     cout << "c++ sort took: " << (double)(clock() - a)/CLOCKS_PER_SEC << " s\n";
  302.  
  303.     a = clock();
  304.     Quicksort1(v2, n);
  305.     cout << "quicksort1 took: " << (double)(clock() - a)/CLOCKS_PER_SEC << " s\n";
  306.    
  307.     a = clock();
  308.     QuicksortH1(v5, n);
  309.     cout << "quicksorth1 took: " << (double)(clock() - a)/CLOCKS_PER_SEC << " s\n";
  310.    
  311.     a = clock();
  312.     Quicksort2(v3, n);
  313.     cout << "quicksort2 took: " << (double)(clock() - a)/CLOCKS_PER_SEC << " s\n";
  314.    
  315.     a = clock();
  316.     QuicksortH2(v6, n);
  317.     cout << "quicksorth2 took: " << (double)(clock() - a)/CLOCKS_PER_SEC << " s\n";
  318.    
  319.     a = clock();
  320.     Quicksort3(v4, n);
  321.     cout << "quicksort3 took: " << (double)(clock() - a)/CLOCKS_PER_SEC << " s\n";
  322.  
  323.     a = clock();
  324.     QuicksortH3(v7, n);
  325.     cout << "quicksorth3 took: " << (double)(clock() - a)/CLOCKS_PER_SEC << " s\n";
  326.    
  327.     bool accepted = true;
  328.     FOR0(i, n) if( v1[i] != v2[i] || v1[i] != v3[i] || v1[i] != v4[i] || v1[i] != v5[i] || v1[i] != v6[i] || v1[i] != v7[i] ){
  329.         accepted = false;
  330.         break;
  331.     }
  332.  
  333.     if( accepted ) cout << "Accepted\n";
  334.     else cout << "Wrong Answer\n";
  335.    
  336.     return 0;
  337. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement