#include <stdio.h>
#include <stdlib.h>
#define MAXINTER (h-1)/u+1
//#define PRINTFILE 0
int *hh,*gg,*cap_inter;
int n,h,u,crt;
int minPoz,maxPoz;
int *sol;
int pozSol=0;
void quicksort(int *prim,int *sec,int st, int dr)
{
int i,j;
int v,t;
if ( dr>st )
{
v=prim[dr]; i=st-1; j=dr; /*indice=ultimul element */
for ( ; ; )
{
while ( prim[++i]>v );
while ( prim[--j]<v );
if (i>=j) break;
t=prim[i];prim[i]=prim[j];prim[j]=t;
if (sec) {t=sec[i];sec[i]=sec[j];sec[j]=t;}
}
t=prim[i];prim[i]=prim[dr];prim[dr]=t;
if (sec) {t=sec[i];sec[i]=sec[dr];sec[dr]=t;}
quicksort(prim,sec,st,i-1);
quicksort(prim,sec,i+1,dr);
}
}
/*
int maxim(int pasi)
{
int ok=0,max=-1,poz=-1,i;
for (i=crt;i>=0;i--)
if (!pus[i] && (hh[i]+u*pasi)<=h)
{
ok=1;
if (hh[i]+u*(pasi+1)<=h) break;
else
if (gg[i]>max) {max=gg[i];poz=i;}
}
if (!ok) return -1;
if (poz==-1) poz=i;
crt=i;
pus[poz]=1;
printf("Aleg gg=%d\n",gg[poz]);
return gg[poz];
}
*/
void afla_intervale()
{
int i;
minPoz=(h-hh[0])/u+1;
for (i=0;i<n;i++)
{
if (cap_inter[2*((h-hh[i])/u+1)]==-1) cap_inter[2*((h-hh[i])/u+1)]=i; //pozitia din stanga a intervalului
cap_inter[2*((h-hh[i])/u+1)+1]=i; //pozitia din dreapta a intervalului
}
maxPoz =(h-hh[n-1])/u+1;
}
void sorteaza_intervale()
{
int i;
for (i=minPoz;i<= maxPoz;i++)
{
if (cap_inter[2*i]==-1) continue;
quicksort(gg,hh,cap_inter[2*i],cap_inter[2*i+1]);
#ifndef PRINTFILE
printf("###%d:\t%d %d###\n",i,cap_inter[2*i],cap_inter[2*i+1]);
#endif
}
}
int minim_lung(int i)
{
if (i<(cap_inter[2*i+1]-cap_inter[2*i]+1)) return i;
else return (cap_inter[2*i+1]-cap_inter[2*i]+1);
}
void construieste_solutia()
{
int i,j;
//din intervalul i tb sa alex maxim i numere
for (i=minPoz;i<= maxPoz;i++)
{
//daca nu e nimic in acel interval
if (cap_inter[2*i]==-1) continue;
for (j=cap_inter[2*i];j<cap_inter[2*i]+minim_lung(i);j++)
{
sol[pozSol++]=gg[j];
#ifndef PRINTFILE
printf("##Aleg pozitia %d cu gg=%d\n",j,gg[j]);
#endif
if (pozSol==i) break;
}
//Depaseste timp
quicksort(sol,NULL,0,pozSol-1);
for (j=j+1;j<cap_inter[2*i]+minim_lung(i);j++)
{
if (sol[pozSol-1]<gg[j])
{
sol[pozSol-1]=gg[j];
#ifndef PRINTFILE
printf("$$Aleg pozitia %d cu gg=%d\n",j,gg[j]);
#endif
//S-ar putea sa depaseasca timp
quicksort(sol,NULL,0,pozSol-1);
}
}
}
}
int main()
{
int i,sum;
FILE *fis=fopen("gutui.in","r");
fscanf(fis,"%d%d%d",&n,&h,&u);
hh=(int*)malloc(n*sizeof(int));
gg=(int*)malloc(n*sizeof(int));
sol=(int*)malloc(n*sizeof(int));
cap_inter=(int*)malloc(2*(h/u+2)*sizeof(int));
for(i=0;i<n;i++)
{fscanf(fis,"%d%d",&hh[i],&gg[i]);}
fclose(fis);
for(i=0;i<2*(h/u+2);i++)
cap_inter[i]=-1;
quicksort(hh,gg,0,n-1);
afla_intervale();
sorteaza_intervale();
construieste_solutia();
#ifndef PRINTFILE
for(i=0;i<n;i++)
printf("hh[%d]=%d gg[%d]=%d\n",i,hh[i],i,gg[i]);
#endif
sum=0;
for(i=0;i<pozSol;i++)
{
#ifndef PRINTFILE
printf("%d ",sol[i]);
#endif
sum+=sol[i];
}
printf("\n");
#ifndef PRINTFILE
printf("Suma totala=%d\n",sum);
#else
FILE *fis1=fopen("gutui.out","w");
fprintf(fis1,"%d\n",sum);
fclose(fis1);
#endif
return 0;
}