Cod sursa(job #2727547)

Utilizator om6gaLungu Adrian om6ga Data 22 martie 2021 04:43:20
Problema Radix Sort Scor 30
Compilator c-32 Status done
Runda Arhiva educationala Marime 4.52 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#pragma GCC optimize("Ofast")


#define max(a, b) ((a) > (b) ? (a) : (b))
#define geth(n) (n->h = 1 + max(n->l->h, n->r->h))

//////////////////////////////////////////////////////

struct node {
    unsigned int key, val, h;
    struct node *l, *r;
} *R, *NIL;

typedef struct node node;
node mem_chunk[10000001];
int chunk_index;
 
void init(void) {
    //R = NIL = (node *) malloc(sizeof(node));
    R = NIL = &mem_chunk[chunk_index++];
    NIL->key = NIL->h = 0,
    NIL->l = NIL->r = NULL;
}
node* rotleft(node *n) {
    node *t = n->l;
    n->l = t->r, t->r = n, geth(n), geth(t);
    return t;
}
node* rotright(node *n) {
    node *t = n->r;
    n->r = t->l, t->l = n, geth(n), geth(t);
    return t;
}
node* balance(node *n) {
    geth(n);
    if (n->l->h > n->r->h + 1) {
        if (n->l->r->h > n->l->l->h)
            n->l = rotright(n->l);
        n = rotleft(n);
    }
    else
        if (n->r->h > n->l->h + 1) {
            if (n->r->l->h > n->r->r->h)
                n->r = rotleft(n->r);
            n = rotright(n);
        }
    return n;
}
node* insert(node *n, unsigned int key, unsigned int val) {
    if (n == NIL) {
        //n = (node *) malloc(sizeof(node));
        n = &mem_chunk[chunk_index++];
        n->key = key, n->val = val, n->h = 1, n->l = n->r = NIL;
        return n;
    }
    if (key < n->key)
        n->l = insert(n->l, key, val);
    else
        n->r = insert(n->r, key, val);
    return balance(n);
}
unsigned myneg = 2<<31;
unsigned int search(node *n, unsigned int key) {
    if (n == NIL) return myneg;
    if (n->key == key) return n->val;
    if (key < n->key)
        return search(n->l, key);
    else
        return search(n->r, key);
}

void inorder(node *n, FILE *out) {
	if (n == NIL)
	    return;
    inorder(n->l, out);
    fprintf(out, "rest[%d] = %d\n", n->key, n->val);
    inorder(n->r, out);
}

//////////////////////////////////////////////////////





int count[256][4], index[256];

void pass(int pass_nr, unsigned int *array, unsigned int *out, int N) {
    int i, sum, j, k;
    unsigned char *c = (unsigned char *)array;

	sum = 0;
	for (i = 0; i < 256; i++) {
		sum += count[i][pass_nr];
		count[i][pass_nr] = sum;
	}
	for (i = 0; i < 256; i++) {
		index[i] = count[i][pass_nr] - 1;
	}
	for (i = 4*N, k = N;;) {
		i -= 4;
		k--;
		//j = c[i+pass_nr];
	    out[index[c[i+pass_nr]]--] = array[k];
	    if (i == 0)
	        break;
	}
}

/*static inline int compar(const void *a, const void *b) {
	unsigned int *x = (unsigned int *)a;
	unsigned int *y = (unsigned int *)b;
	
	return (*x > *y) + (*x == *y)*0 + (*x < *y)*(-1);
}*/

unsigned int array_in[10000001];
unsigned int array_out[10000001];


int main() {
    FILE *in=fopen("radixsort.in","r");
    FILE *out=fopen("radixsort.out","w");
    int N, A, B, C, i, n, treshold;
	unsigned long long int vi;
	unsigned char *c = (unsigned char *)array_in;
	unsigned int aux, aux2, flag;
	unsigned int a2_31 = (2<<31);

	fscanf(in,"%d %d %d %d",&N, &A, &B, &C);
	init();
	
	/*for (i = 0; i < C; i++) {
		array_out[i] = a2_31;
	}*/

	array_in[0] = B;
	vi = B;
	for (i = 1; i < N; i++) {
		aux = array_in[i-1];
		aux2 = search(R, aux);
		if (aux2 != a2_31) {
			array_in[i] = aux2;
			vi = aux2;
			continue;
		}
		vi = (A*vi+B)%C;
	    array_in[i] = vi;
		R = insert(R, aux, array_in[i]);
		
		/*aux = array_in[i-1];
		aux2 = array_out[aux];
		flag = (aux2 & a2_31);
		
	    if (flag) {
	    	array_in[i] = aux2;
	    	continue;
		}
		//vi = A*aux + B;
		//vi -= (vi/C)*C;
		vi = (A*aux+B)%C;
	    array_in[i] = vi;
		array_out[aux] = array_in[i];
	    //array_in[i] = rest[array_in[i-1]];*/
	    
	    //vi = A*vi + B;
		//vi -= (vi/C)*C;
		
		/*vi = A*vi + B;
		vi -= (vi/C)*C;
	    array_in[i] = vi;*/
	    
	    /*aux2 = search(R, aux);
		if (aux2 == a2_31) {
			R = insert(R, aux, array_in[i]);
		}*/
	}
	
	for (i = 4*N;;) {
		i -= 4;
	    count[c[i]][0]++;
	    count[c[i+1]][1]++;
	    count[c[i+2]][2]++;
	    count[c[i+3]][3]++;
	    if (i == 0)
	        break;
	}
	
	pass(0, array_in, array_out, N);
	pass(1, array_out, array_in, N);
	pass(2, array_in, array_out, N);
	pass(3, array_out, array_in, N);
	
    //qsort(array_in, N, sizeof(unsigned int), compar);
	
	for (i = 0; i < N; i += 10)
	    fprintf (out, "%d ", array_in[i]);
    fprintf(out, "\n");
    
	//inorder(R, out);

	fclose(in);
	fclose(out);
	
	return 0;
}