Title Description
The enemy has \ (n \) blame, each attack is \ (a_i \) , blood is \ (D_i \) .
It had only one attack is \ (b \) is strange.
Each round of fighting procedures:
- We select some blame the enemy to attack, make blood less \ (b \) , if this time the blame blood \ (\ Leq \) 0 while in death.
- If the enemy of \ (i \) blame is still alive, then for our cause \ (a_i \) damage.
You can select the initial enemy were two strange spike.
Seeking suffered injuries minimum.
solution:
Obviously we only blame in a row after a lethal attack, will be replaced one. The first set \ (i \) blame needs to be continuous attack:
If there is no spike operation, only consider the attack order.
The section \ (I \) blame ranked \ (J \) only after, if and only if:
So we can follow this sort keywords.
Now consider spike operation. If only blame a spike, the damage value will be reduced:
If it is determined considering the first spike \ (I \) blame, then the first spike \ (J \) blame than the first spike \ (K \) blame excellent (where \ (J \) , \ (K \) < \ ( I \) and \ (C_J \) > \ (C_K \) ), if and only if:
Simplification was:
This is a slope optimization model (do not know, then turn right slope optimization ), obviously you can use dynamic Lie tree maintenance, but I will not , we abscissa c, e is ordinate axes, may become optimal decision only the convex point.
Maintains a monotonically decreasing to the convex hull.
But noted that \ (a_i \) and \ (c_j \) disorder.
Consider \ (CDQ \) partition process.
For the interval \ ([L, R & lt] \) , the \ ([l, mid] \ ) and \ ([mid + 1, r ] \) respectively \ (C \) and \ (A \) sorting, i.e., The slope can be optimized.
Complexity \ (O (nlog ^ 2n) \) .
Code:
//#pragma GCC optimize(2)
//#pragma GCC optimize(3, "Ofast", "inline")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int N=1e6+5;
const ll mod=998244353;
const double eps=1e-5;
const double pi=acos(-1);
#define ls p<<1
#define rs p<<1|1
struct node
{
ll x,y,z;
}a[N];
int q[N];
bool cmp(node x,node y)
{
return x.x*y.y>x.y*y.x;
}
bool cmpy(node x,node y)
{
return x.y<y.y;
}
bool cmpx(node x,node y)
{
return x.x<y.x;
}
ll ans,sum;
void cdq(int l,int r)
{
if(l==r) return;
int mid=(l+r)>>1;
cdq(l,mid);cdq(mid+1,r);
sort(a+l,a+mid+1,cmpy);sort(a+mid+1,a+r+1,cmpx);
int s=1,e=1;q[1]=0;
for(int i=l;i<=mid;i++)
{
while(s<e&&(a[q[e]].z-a[q[e-1]].z)*(a[i].y-a[q[e]].y)<=(a[i].z-a[q[e]].z)*(a[q[e]].y-a[q[e-1]].y)) e--;
q[++e]=i;
}
for(int i=mid+1;i<=r;i++)
{
while(s<e&&(a[q[s]].z-a[q[s+1]].z)<=a[i].x*(a[q[s]].y-a[q[s+1]].y)) s++;
ans=min(ans,sum-a[i].z-a[q[s]].z+a[i].x*a[q[s]].y);
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
int n,m;
ll A=0,B=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i].x>>a[i].y;
A+=a[i].x;a[i].y=(a[i].y-1)/m+1;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)
{
A-=a[i].x;B+=a[i].y;
a[i].z=a[i].x*(B-1)+A*a[i].y;
sum+=a[i].x*(B-1);
}
ans=sum;
cdq(1,n);
cout<<ans<<endl;
return 0;
}