#define _USE_MATH_DEFINES

#include <bits/stdc++.h>

// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
 
using namespace std;
// using namespace __gnu_pbds;
// template<class T> using ordered_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

#define ll long long int
#define ull unsigned long long int
 
#define lp(i,n) 	    for(int i=0;i<(int)(n);i++)
#define lpi(i, j, n)    for(int i=(j);i<(int)(n);i++)
#define lpd(i, j, n)    for(int i=(j);i>=(int)(n);i--)
 
#define all(v)  	 ((v).begin()), ((v).end())
#define sz(v)    	 ((int)((v).size()))
#define clr(v, d)    memset(v, d, sizeof(v))
#define PB           push_back
#define MP           make_pair
#define N 200005
 
#define PI 3.14159265359
 
 
ll nChooseR(int n,int k);
ll gcd(ll a, ll b);
vector<string> split(string target,unsigned char c );


ll n,k,t,m,x,y,a[N],st[N*4],lazy[N*4];

bool isPrime(ll h); 

ll ans;

ll mod=1e9 +7;

vector<pair<ll,ll>>p;
void build(int l,int r,int root=0){
	if(l==r){
		st[root]=p[l].second;
		return;
	}
	int mid=(l+r)/2;
	build(l,mid,root*2+1);
	build(mid+1,r,root*2 +2);
	st[root]=st[root*2 +1]+st[root*2 +2];
}
void updateRange(int l,int r,int ql,int qr,ll val, int root=0){
	if(lazy[root]!=0){
		st[root]+= (r-l+1)*lazy[root];
		if(l!=r)
			lazy[root*2+1]+=lazy[root],lazy[root*2 +2]+=lazy[root];
		lazy[root]=0;
	}
	if(l>qr || r<ql)return;
	if(l>=ql && r<=qr){
		st[root]+=(r-l+1)*val;
		if(r!=l)
			lazy[root*2+1]+=val,lazy[root*2 +2]+=val;
		
		return;
	}
	int mid=(r+l)/2;
	updateRange(l,mid,ql,qr,val,root*2 +1);
	updateRange(mid+1,r,ql,qr,val,root*2 +2);

	st[root]=st[root*2+1]+st[root*2 +2];
}

ll getVal(int l,int r,int i,int root=0){

	if(lazy[root]!=0){
		st[root]+=lazy[root]*(r-l+1);
		if(l!=r)
			lazy[root*2+1]+=lazy[root],lazy[root*2 +2]+=lazy[root];

		lazy[root]=0;
	}
	if(l>i || r<i)return 0ll;
	if(l==r)return st[root];
	

	int mid=(r+l)/2;
	return getVal(l,mid,i,root*2 +1)+getVal(mid+1,r,i,root*2 +2);

}



int main() {
// freopen("pyramid.in","r",stdin); 
  //freopen("output.txt","w",stdout); 
cout.precision(10);
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin>>n>>m>>k;
p.resize(n);
lp(i,n)cin>>p[i].first>>p[i].second;
sort(all(p));
lp(i,n)a[i]=p[i].first;

build(0,n-1);
lp(i,n){
	ll val=getVal(0,n-1,i);
	if(val>0){
		ans+=(val+k-1)/k;
		auto r=upper_bound(a+i,a+n,a[i]+2*m)-a;
		updateRange(0,n-1,i,r-1,((val+k-1)/k) *-1*k);
	}
}
cout<<ans;




}
 
	
ll nChooseR( int n, int k )
{
    if (k > n) return 0;
    if (k * 2 > n) k = n-k;
    if (k == 0) return 1;
   	ll result = n;
    for( int i = 2; i <= k; ++i ) {
        result *= (n-i+1);
        result /= i;
    }
    return result;
}
 
ll gcd(ll a, ll b){
	return b==0?a:gcd(b,a%b);
	}
 
 
vector<string> split(string target,unsigned char c ){
	string d="";
	vector<string>arr;
	for(auto n:target)
	{
		if(n!=c)
		d+=n;
		else if(d!="")
		arr.push_back(d),d="";
	}
	if (d!="")
	arr.push_back(d),d="";
	return arr;
}
// bool isPrime(ll h){
//      for(ll i=0;primes[i]*primes[i]<= h;i++)
//      if (h%primes[i]==0)
//      	return 0;
//      return h!=1;
//  }
 bool isPrime(ll g){
   if((g%2==0 && g>2) || g==1)return 0;
   for(ll i=3;i*i<=g;i+=2)if(g%i==0)return 0;
   return 1;   
 
 }

Measured memory_bytes: 17280