Pagini recente » Cod sursa (job #690674) | Cod sursa (job #932578) | Cod sursa (job #817287) | Cod sursa (job #2668821) | Cod sursa (job #1558257)
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_VALUE 2000000001
#define Nadejde 700000
#define R 524287
#define MAX_LEVEL 20
/** Implementare K-th element!
* Ne vom folosi de structura Skip-Lists.
* Pe langa zona de memorie, vom retine si un vector "d", cu
* urmatoarea semnificatie:
* "Vectorul "d" reprezinta distanta pana la urmatorul element
* din nivel."
*
* Pentru mai multe informatii:
*
http://drum.lib.umd.edu/bitstream/
handle/1903/544/CS-TR-2286.1.pdf;jsessionid=4F143B4B585765118DC
2CD0217A2AF21?sequence=2
*
* Multumim Doamne!
**/
int N, K;
int level; // nivelul maxim al fiecatui element.
int bufPtr; // primul slot nealocat.
int d[Nadejde]; // distanta pana la urmatorul element din nivel.
int sl[Nadejde]; // zona de memorie prealocata.
int space[MAX_LEVEL]; // folosit in timpul selectiei.
int update[MAX_LEVEL]; // folosit in timpul inserarii.
/** Initializeaza structura. **/
void init() {
sl[0] = -MAX_VALUE;
sl[MAX_LEVEL + 1] = MAX_VALUE;
int l;
for (l = 0; l < MAX_LEVEL; l++) {
sl[l + 1] = MAX_LEVEL + 1;
d[l + 1] = 1;
}
bufPtr = MAX_LEVEL + 2;
level = 1;
}
/** Da-mi un nivel random. **/
int randomLevel() {
int l = 1, r;
for (r = rand() & R; r & 1; r >>= 1) {
l++;
}
return l;
}
/** Insereaza valoarea "x" in lista de nivel "0". **/
void lowLevel(int x) {
sl[bufPtr] = x;
d[bufPtr + 1] = 1;
sl[bufPtr + 1] = sl[update[0] + 1];
sl[update[0] + 1] = bufPtr;
}
/** Insereaza valoarea "x" in structura. **/
void insert(int x) {
int l, save, pos = 0;
/* Cauta pointerii ce trebuie actualizati. */
for (l = level - 1; l >= 0; l--) {
space[l] = 0;
while (sl[sl[pos + l + 1]] < x) {
space[l] += d[pos + l + 1];
pos = sl[pos + l + 1];
}
update[l] = pos;
}
for (l = level; l < MAX_LEVEL; l++) {
update[l] = space[l] = 0;
}
int newLevel = randomLevel();
if (newLevel > level) {
level = newLevel;
}
/* Introdu-l pe "x" in structura, restabilind pointerii si distantele. */
lowLevel(x);
for (l = 1; l < newLevel; l++) {
save = space[l - 1] + d[update[l - 1] + l];
d[bufPtr + l + 1] = d[update[l] + l + 1] - save + 1;
d[update[l] + l + 1] = save;
sl[bufPtr + l + 1] = sl[update[l] + l + 1];
sl[update[l] + l + 1] = bufPtr;
}
for (l = newLevel; l < MAX_LEVEL; l++) {
d[update[l] + l + 1]++;
}
bufPtr += newLevel + 1;
}
/** Sterge valoarea "x" din structura. **/
void erase(int x) {
int l, pos = 0;
for (l = level - 1; l >= 0; l--) {
while (sl[sl[pos + l + 1]] < x) {
pos = sl[pos + l + 1];
}
update[l] = pos;
}
for (l = level; l < MAX_LEVEL; l++) {
update[l] = 0;
}
pos = sl[pos + 1];
l = 0;
while ((l < level) && (sl[update[l] + l + 1] == pos)) {
d[update[l] + l + 1] += d[pos + l + 1] - 1;
sl[update[l] + l + 1] = sl[pos + l + 1];
l++;
}
while (l < MAX_LEVEL) {
d[update[l] + l + 1]--;
l++;
}
}
/** Sterge elementul de pe pozitia "k". **/
void erasebyGrade(int k, FILE *f) {
int l, pos = 0, grade = 0;
for (l = level - 1; l >= 0; l--) {
while (grade + d[pos + l + 1] <= k) {
grade += d[pos + l + 1];
pos = sl[pos + l + 1];
}
update[l] = pos;
}
for (l = level; l < MAX_LEVEL; l++) {
update[l] = 0;
}
fprintf(f, "%d ", sl[pos]);
l = 0;
while ((l < level) && (sl[update[l] + l + 1] == pos)) {
d[update[l] + l + 1] += d[pos + l + 1] - 1;
sl[update[l] + l + 1] = sl[pos + l + 1];
l++;
}
while (l < MAX_LEVEL) {
d[update[l] + l + 1]--;
l++;
}
}
/** Da-mi elementul de pe pozitia "k". **/
int listSelect(int k) {
int l, pos = 0, grade = 0;
for (l = level - 1; l >= 0; l--) {
while (grade + d[pos + l + 1] <= k) {
grade += d[pos + l + 1];
pos = sl[pos + l + 1];
}
}
return sl[pos];
}
int main(void) {
int i, x, last = 2;
FILE *in = fopen("order.in", "r");
FILE *out = fopen("order.out", "w");
init();
srand(time(NULL));
/* Citeste intrebarile. */
fscanf(in, "%d", &N);
for (i = 1; i <= N; i++) {
insert(i);
}
fclose(in);
for (i = 0; i < N; i++) {
x = (last + i) % (N - i);
x = !x ? N - i : x;
last = x;
erasebyGrade(x, out);
}
fclose(out);
/// Multumim Doamne!
puts("Doamne ajuta!");
return 0;
}