#include <stdio.h>
#include <stdlib.h>
typedef struct gutui
{
int size;
int weight;
}Gutue;
typedef struct wei
{
int weight;
struct wei * next;
struct wei * prev;
}Weights,*AWeights;
AWeights makeNode(int x)
{
AWeights aux=(AWeights) malloc(sizeof(Weights));
aux->weight=x;
aux->next=NULL;
aux->prev=NULL;
return aux;
}
void printL(AWeights L)
{
while(L!=NULL)
{
printf("%i ",L->weight);
L=L->next;
}
printf("\n");
}
int remr(int x, AWeights * lista)
{
printf("remover %i\n",x);
AWeights L = *lista;
int aux;
if(L==NULL)
return 0;
if(L->weight>x)
{
if(L->next!=NULL)
L->next->prev=NULL;
(*lista)=L->next;
aux=L->weight;
free(L);
return aux;
}
else
return 0;
}
void insertr(int x, AWeights * lista)
{
printf("insertr %i\n",x);
AWeights L = *lista;
AWeights aux = makeNode(x);
if((*lista) == NULL)
{
(*lista)=aux;
return;
}
if(L->weight<x)//if(L->weight<x)
{
L->prev=aux;
aux->next=L;
*lista=aux;
return;
}
while(L->next!=NULL && L->next->weight>=x)//while(L->next!=NULL && L->next->weight>=x)
{
L=L->next;
}
if(L->next==NULL)
{
aux->prev=L;
L->next=aux;
}
else
{
L=L->next;
L->prev->next=aux;
aux->prev=L->prev;
aux->next=L;
L->prev=aux;
}
}
int rem(int x, AWeights * lista, AWeights * rlista)
{
printf("remove %i\n",x);
AWeights L = *lista;
int aux;
if(L==NULL)
return 0;
if(L->weight<x)
{
if(L->next!=NULL)
L->next->prev=NULL;
(*lista)=L->next;
aux=L->weight;
free(L);
insertr(aux,rlista);
return aux;
}
else
return 0;
}
int insert(int x, AWeights * lista, AWeights * rlista)
{
printf("insert %i\n",x);
int auxx=remr(x,rlista);
if(auxx!=0)
{
insertr(x,rlista);
x=auxx;
}
AWeights L = *lista;
AWeights aux = makeNode(x);
if((*lista) == NULL)
{
(*lista)=aux;
return x;
}
if(L->weight>x)//if(L->weight<x)
{
L->prev=aux;
aux->next=L;
*lista=aux;
return x;
}
while(L->next!=NULL && L->next->weight<=x)//while(L->next!=NULL && L->next->weight>=x)
{
L=L->next;
}
if(L->next==NULL)
{
aux->prev=L;
L->next=aux;
}
else
{
L=L->next;
L->prev->next=aux;
aux->prev=L->prev;
aux->next=L;
L->prev=aux;
}
return x;
}
int rule(const void * a, const void *b)
{
Gutue * A = (Gutue *) a;
Gutue * B = (Gutue *) b;
if(A->size > B->size)
return -1;
else if(A->size < B->size)
return 1;
else
return B->weight-A->weight;
}
int main(int argc, char **argv)
{
int maxsize, dif, removed, aux, step, n, i, total=0;
int rest=0;
AWeights lista=NULL;
AWeights rlista=NULL;
FILE * in = fopen("gutui.in","rt");
FILE * out = fopen("gutui.out","wt");
//Read data
fscanf(in,"%i %i %i",&n,&maxsize,&step);
Gutue *gut = (Gutue *) malloc(sizeof(Gutue) * n);
dif=maxsize%step;
for(i=0;i<n;i++)
{
fscanf(in,"%i %i",&(gut[i].size),&(gut[i].weight));
if(gut[i].size>maxsize)
{
i--;
n--;
}
else
{
if(gut[i].size%step>dif)
gut[i].size+=step;
gut[i].size/=step;
}
}
maxsize++;
maxsize/=step;
//Read data
qsort(gut,n,sizeof(Gutue),rule);
for(i=0;i<n;i++)
{
printf("%i %i\n",gut[i].size,gut[i].weight);
}
maxsize++;
for(i=0;i<n;i++)
{
rest+=maxsize-gut[i].size;
aux=gut[i].size;
while(gut[i].size==aux && rest>0 && i<n)
{
total+=insert(gut[i].weight,&lista,&rlista);
printL(lista);
i++;
rest--;
}
if(rest==0)
{
removed=1;
while(gut[i].size==aux && i<n)
{
removed = rem(gut[i].weight, &lista, &rlista);
printL(lista);
total-=removed;
if(removed)
{
total+=insert(gut[i].weight,&lista, &rlista);
printL(lista);
}
else
break;
i++;
}
while(gut[i].size==aux && i<n)
i++;
}
i--;
maxsize=aux;
}
fprintf(out,"%i\n",total);
//printL(lista);
scanf("%i",&i);
fclose(in);
fclose(out);
return 0;
}