适者
\[\sum_{i=1}^na_i\sum_{j=1}^ip_i-1
\]
\[考虑i,j
\\
i在j前:sum+a_i*(p_i-1)+a_j*(p_i+p_j-1)=sum+a_i*p_i-a_i+a_j*p_i+a_j*p_j-a_j
\\
j在i前:sum+a_j*(p_j-1)+a_i*(p_i+p_j-1)=sum+a_j*p_j-a_j+a_i*p_i+a_i*p_j-a_i
\\
\delta =a_j*p_i-a_i*p_j
\\
于是i在j前的必要条件是,a_j*p_i<a_i*p_j
\]
\[再考虑有秒杀的条件
\\
考虑i被秒杀后的影响为t_i
\\
t_i=(\sum_{j=1}^{i}(d_j-1)*a_i)+(\sum_{j=i+1}^{n}a_j*d_i)
\\
而对于i,j,产生的影响则为,t_i+t_j-a_i*d_j(等同于减去i的攻击在j的贡献)
\]
\[再考虑固定i,则寻找j使上式最大
\\
决策点j_1<j_2,f(j1)<f(j2)
\\
t_{j_1}-a_id_{j_1}<t_{j_2}-a_id_{j_2}
\\
a_i(d_{j_2}-d_{j_1})<t_{j_2}-t_{j_1}
\\
上凸壳
\]
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=6e5+5;
int n;
int a[MAXN];
int dq[MAXN];
int d[MAXN];
int t[MAXN];
int sumw[MAXN];
int dp[MAXN];
struct Query{
int pos;
int sloop;
}query[MAXN],tmp[MAXN];
bool cmp(Query x,Query y)
{
// return x.sloop<y.sloop;
if(x.sloop==y.sloop)
{
return x.pos<y.pos;
}
return x.sloop>y.sloop;
}
int X(int i)
{
return d[i];
}
int Y(int i)
{
return t[i];
}
void solve(int l,int r)
{
if(l==r)
{
return;
}
int mid=(l+r)>>1;
int lpo=l;
int rpo=mid+1;
for(int i=l;i<=r;i++)
{
if(query[i].pos<=mid)
{
tmp[lpo++]=query[i];
}else
{
tmp[rpo++]=query[i];
}
}
for(int i=l;i<=r;i++)
{
query[i]=tmp[i];
}
solve(l,mid);
int tail=0;
for(int i=l;i<=mid;i++)
{
while(tail>1&&(Y(query[i].pos)-Y(dq[tail]))*(X(dq[tail])-X(dq[tail-1]))>=(X(query[i].pos)-X(dq[tail]))*(Y(dq[tail])-Y(dq[tail-1])))
{
tail--;
}
dq[++tail]=query[i].pos;
}
for(int i=mid+1;i<=r;i++)
{
while(tail>1&&query[i].sloop*(X(dq[tail])-X(dq[tail-1]))>=(Y(dq[tail])-Y(dq[tail-1])))
{
tail--;
}
// printf("%d\n",dq[head]);
dp[query[i].pos]=max(dp[query[i].pos],t[query[i].pos]+t[dq[tail]]-a[query[i].pos]*d[dq[tail]]);
}
solve(mid+1,r);
lpo=l;
rpo=mid+1;
int poi=l;
while(lpo<=mid&&rpo<=r)
{
if((X(query[lpo].pos)<X(query[rpo].pos))||((X(query[lpo].pos)==X(query[rpo].pos)&&Y(query[lpo].pos)>Y(query[rpo].pos))))
{
tmp[poi++]=query[lpo++];
}
else
{
tmp[poi++]=query[rpo++];
}
}
while(lpo<=mid)
{
tmp[poi++]=query[lpo++];
}
while(rpo<=r)
{
tmp[poi++]=query[rpo++];
}
for(int i=l;i<=r;i++)
{
query[i]=tmp[i];
}
}
int ATK;
struct node{
int x,y;
}qr[MAXN];
bool XP(node x,node y)
{
return y.x*x.y<y.y*x.x;
}
signed main()
{
//freopen("1.in","r",stdin);
// freopen("fight2.out","w",stdout);
scanf("%lld %lld",&n,&ATK);
int sumd=0;
for(int i=1;i<=n;i++)
{
scanf("%lld %lld",&a[i],&d[i]);
d[i]=(d[i]-1)/ATK+1;
//t[i]=
qr[i].x=a[i];
qr[i].y=d[i];
}
sort(qr+1,qr+1+n,XP);
int ans=0;
sumd=0;
for(int i=1;i<=n;i++)
{
sumd+=(qr[i].y);
ans+=((sumd-1)*qr[i].x);
}
for(int i=1;i<=n;i++)
{
a[i]=qr[i].x;
d[i]=qr[i].y;
}
sumd=0;
for(int i=1;i<=n;i++)
{
sumd=sumd+(d[i]);
t[i]=(sumd-1)*a[i];
}
int suma=0;
for(int i=n;i>=1;i--)
{
t[i]+=suma*d[i];
suma+=a[i];
}
for(int i=1;i<=n;i++)
{
query[i].pos=i;
query[i].sloop=a[i];
}
memset(dp,0,sizeof(dp));
sort(query+1,query+1+n,cmp);
solve(1,n);
//printf("%lld",dp[n]);
int rg=0;
for(int i=1;i<=n;i++)
{
rg=max(rg,dp[i]);
}
// printf("%lld\n",ans);
printf("%lld",ans-rg);
}