Daguai (CDQ Partition Optimization + slope)

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:

\[c_i=\lfloor \frac{d_i-1}{b} \rfloor +1 \]

If there is no spike operation, only consider the attack order.
The section \ (I \) blame ranked \ (J \) only after, if and only if:

\[c_i*a_j>c_j*a_i \]

So we can follow this sort keywords.
Now consider spike operation. If only blame a spike, the damage value will be reduced:

\[e_i=a_i\sum_{j=1}^ {i-1}c_j+a_i(c_i-1)+c_i\sum_{j=i+1}^{n}a_j \]

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:

\[e_i+e_j-a_i*c_j>e_k+e_i-a_i*c_k \]

Simplification was:

\[a_i> \frac {e_j-e_k}{c_j-c_k} \]

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;
}

Guess you like

Origin www.cnblogs.com/Suiyue-Li/p/12575573.html