Problem:
Score : 600 points

Problem Statement

Silver Fox is fighting with N monsters.

The monsters are standing in a row, and we can assume them to be standing on a number line. The i-th monster, standing at the coordinate X_i, has the health of H_i.

Silver Fox can use bombs to attack the monsters.
Using a bomb at the coordinate x decreases the healths of all monsters between the coordinates x-D and x+D (inclusive) by A.
There is no way other than bombs to decrease the monster's health.

Silver Fox wins when all the monsters' healths become 0 or below.

Find the minimum number of bombs needed to win.

Constraints

1 \leq N \leq 2 \times 10^5

0 \leq D \leq 10^9

1 \leq A \leq 10^9

0 \leq X_i \leq 10^9

1 \leq H_i \leq 10^9

X_i are distinct.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N D A
X_1 H_1
:
X_N H_N

Output

Print the minimum number of bombs needed to win.

Sample Input 1

3 3 2
1 2
5 4
9 2

Sample Output 1

2

First, let us use a bomb at the coordinate 4 to decrease the first and second monsters' health by 2.

Then, use a bomb at the coordinate 6 to decrease the second and third monsters' health by 2.

Now, all the monsters' healths are 0.
We cannot make all the monsters' health drop to 0 or below with just one bomb.

Sample Input 2

9 4 1
1 5
2 4
3 3
4 2
5 1
6 2
7 3
8 4
9 5

Sample Output 2

5

We should use five bombs at the coordinate 5.

Sample Input 3

3 0 1
300000000 1000000000
100000000 1000000000
200000000 1000000000

Sample Output 3

3000000000

Watch out for overflow.

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iostream>
using namespace std;
#define re register
#define ll long long
#define int ll
inline int gi(){
	int f=1,sum=0;char ch=getchar();
	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
	return f*sum;
}
const int N=200010;
struct node
{
	int x,h;
	bool operator<(const node &b)const{return x<b.x;}
}p[N];
int t[N<<2],tag[N<<2],L[N<<2],R[N<<2],n,d,A,o[N];
void pushdown(int o)
{
	if(tag[o])
	{
		t[o<<1]-=tag[o]*(R[o<<1]-L[o<<1]+1);
		t[o<<1|1]-=tag[o]*(R[o<<1|1]-L[o<<1|1]+1);
		tag[o<<1]+=tag[o];
		tag[o<<1|1]+=tag[o];
		tag[o]=0;
	}
}
void pushup(int o)
{
	t[o]=t[o<<1]+t[o<<1|1];
}
void build(int o,int l,int r)
{
	tag[o]=0;L[o]=l;R[o]=r;
	if(l==r){t[o]=p[l].h;return;}
	int mid=(l+r)>>1;
	build(o<<1,l,mid);build(o<<1|1,mid+1,r);
	pushup(o);
}
void modify(int o,int l,int r,int posl,int posr,int val)
{
	if(posl<=l&&r<=posr)
	{
		tag[o]+=val;t[o]-=val*(r-l+1);
		return;
	}
	int mid=(l+r)>>1;pushdown(o);
	if(posl<=mid)modify(o<<1,l,mid,posl,posr,val);
	if(mid<posr)modify(o<<1|1,mid+1,r,posl,posr,val);
	pushup(o);
}
int query(int o,int l,int r,int pos)
{
	if(l==r)return t[o];
	int mid=(l+r)>>1;pushdown(o);
	if(pos<=mid)return query(o<<1,l,mid,pos);
	else return query(o<<1|1,mid+1,r,pos);
}
signed main()
{
	n=gi();d=gi();A=gi();
	for(int i=1;i<=n;i++)p[i].x=o[i]=gi(),p[i].h=gi();
	sort(o+1,o+n+1);int tot=unique(o+1,o+n+1)-o-1;
	for(int i=1;i<=n;i++)p[i].x=lower_bound(o+1,o+tot+1,p[i].x)-o,p[i].h=p[i].h/A+(p[i].h%A?1:0);
	sort(p+1,p+n+1);ll ans=0;build(1,1,n);
	for(int i=1;i<=n;i++)
	{
		if(query(1,1,n,i)<=0)continue;int nd=query(1,1,n,i);
		int P=lower_bound(o+1,o+tot+1,o[p[i].x]+2*d)-o;if(o[p[i].x]+2*d>=o[tot])P=n;
		modify(1,1,n,i,P,nd);ans+=nd;
	}
	printf("%lld\n",ans);
	return 0;
}