#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef void *T;
struct heap_s {
int size;
int capacity;
T *data;
};
typedef struct heap_s *Heap;
/*
* Functia H_New creaza un heap nou cu capacitatea 'max'
* aloca memorie pentru el, si returneaza adresa lui
*/
Heap H_New(int max)
{
Heap heap;
assert(max > 0);
heap = (struct heap_s *) malloc(sizeof(struct heap_s));
heap->size = 0;
heap->capacity = max;
heap->data = (T*)malloc((heap->capacity) * sizeof(T));
return heap;
}
/*
* Functia elibereaza memoria folosita de heap.
*/
void H_Delete(Heap heap)
{
assert(heap);
heap->capacity = 0;
heap->size = 0;
if (heap->data) /* este posibil ca vectorul sa nu fie alocat */
free(heap->data);
free(heap);
}
/* Returneaza 1 daca heapul este gol si 0 daca contine elemente */
int H_Empty(Heap heap)
{
assert(heap);
return heap->size == 0;
}
/* Returneaza 1 daca heapul a atins capacitatea maxima */
int H_Full(Heap heap)
{
assert(heap);
return heap->size == heap->capacity;
}
/* Returneaza primul element din heap */
T H_FindMin(Heap heap)
{
assert(heap);
assert(heap->size > 0);
return heap->data[0];
}
static void H_Down(Heap h, int p, int (*compare) (T x, T y));
static void H_Up(Heap h, int p, int (*compare) (T x, T y));
/* Sterge primul element din heap si actualizeaza heapul */
void H_RemoveMin(Heap heap, int compare(T x, T y))
{
T x;
assert(heap);
assert(heap->size > 0);
assert(compare);
x = heap->data[0];
heap->data[0] = heap->data[--heap->size];
H_Down(heap, 0, compare);
}
void H_Insert(Heap * heap, T key, int compare(T x, T y))
{
int i, capacity;
assert(heap);
assert(*heap);
assert((*heap)->size >= 0);
if ((*heap)->size == (*heap)->capacity) {
T *data;
capacity = (*heap)->capacity;
data = (*heap)->data;
(*heap)->data = NULL;
H_Delete(*heap);
*heap = H_New(capacity*2);
(*heap)->size = capacity;
for (i = 0; i < (*heap)->size; i++)
(*heap)->data[i] = data[i];
assert(data);
free(data);
}
(*heap)->data[(*heap)->size++] = key;
H_Up(*heap, (*heap)->size - 1, compare);
}
/* Returneaza numarul de elemente din heap */
int H_Size(Heap heap)
{
assert(heap);
return heap->size;
}
/* Returneaza capacitatea heapului */
int H_Capacity(Heap heap)
{
assert(heap);
return heap->capacity;
}
/* Functia Coboara elementul din pozitia p si actualizeaza heapul */
static void H_Down(Heap h, int p, int (*compare) (T x, T y))
{
int fiu;
T t;
while (2 * p + 1 < h->size) {
fiu = 2 * p + 1;
if (fiu + 1 < h->size && compare(h->data[fiu], h->data[fiu
+ 1]) > 0) {
fiu++;
}
if (compare(h->data[fiu], h->data[p]) < 0) {
t = h->data[p];
h->data[p] = h->data[fiu];
h->data[fiu] = t;
p = fiu;
} else {
break;
}
}
}
/* Functia Urca elementul din pozitia p si actualizeaza heapul */
static void H_Up(Heap h, int p, int (*compare) (T x, T y))
{
T aux;
if (p == 0)
return;
while (p > 0
&& (compare(h->data[p], h->data[(p - 1) / 2]) <
0)) {
aux = h->data[p];
h->data[p] = h->data[(p - 1) / 2];
h->data[(p - 1) / 2] = aux;
p = (p - 1) / 2;
}
}
int N,H,U;
typedef struct {
int h;
int g;
} gutuie;
int comp(T a, T b) {
return *(int*)a - *(int*)b;
}
int main() {
FILE * f;
FILE * g;
f=fopen( "gutui.in","r");
g=fopen("gutui.out","w");
fscanf(f,"%d %d %d",&N,&H,&U);
int i,j;
gutuie v[N];
for (i=0;i<N;i++) {
int a,b;
fscanf(f,"%d %d",&a,&b);
if (a<=H) {
v[i].h=a;
v[i].g=b;
} else {
N--;
i--;
continue;
}
}
for (i=0;i<N;i++)
for (j=i+1;j<N;j++) {
if ((H-v[i].h)/U > (H-v[j].h)/U) {
gutuie aux=v[i];
v[i]=v[j];
v[j]=aux;
}
if ( (H-v[i].h)/U == (H-v[j].h)/U && v[i].g < v[j].g) {
gutuie aux=v[i];
v[i]=v[j];
v[j]=aux;
}
}
for (i=0;i<N;i++)
;//printf("%d %d\n",v[i].h,v[i].g);
Heap heap = H_New(N);
for (i=0;i<N;i++)
;//H_Insert(&heap,&v[i].g,comp);
int niv=(H-v[0].h)/U; int count=niv;
for (i=0;i<N;i++)
if ( (H-v[i].h)/U == niv ) {
if ( H_Size(heap) < niv+1 ) {
H_Insert(&heap,&v[i].g,comp);
count--;
continue;
}
if ( H_Size(heap)==niv+1 && count>=0)
if (*(int*)H_FindMin(heap)<v[i].g) {
H_RemoveMin(heap,comp);
H_Insert(&heap,&v[i].g,comp);
count--;
continue;
}
if (count<0) {
niv++;
count=niv;
}
} else if ( (H-v[i].h)/U > niv ) {
niv = (H-v[i].h)/U;
count=niv;
i--;
continue;
}
int suma=0;
while ( H_Size(heap)>0) {
printf("%d ",*((int*)H_FindMin(heap)));
suma+=*((int*)H_FindMin(heap));
H_RemoveMin(heap,comp);
}
printf("\n");
fprintf(g,"%d\n",suma);
fclose(g);
return 0;
}