Description
埃蒙的军队部署在 n 个星球,星球的编号分别为 1,⋯ ,n1,\cdots,n1,⋯,n
埃蒙在第 iii 个星球驻扎着 pip_ ipi个单位的军队。据可靠情报,若干天后指挥官们会往第 iii 个星球派出 si 个单位的军队。
星球两两之间具有时空航道,埃蒙可以从起点星球发射一架最多容纳 ccc 个单位部队的穿梭机到终点星球。但是,这些时空航道都是单向的,穿梭机只能从编号更小的星球运送部队到编号更大的星球。埃蒙可以以任意顺序发射这些穿梭机,但每条时空航道只能使用一次。
111个单位的埃蒙部队可以牵制111个单位的指挥官部队。现在埃蒙想要知道他最多能牵制多少指挥官们的军队。
n≤105n \le 10^5n≤105
考虑建立网络流,从SSS向所有星球连边,容量sis_isi,从星球向TTT连边容量cic_ici,编号小的星球向大的星球连边,容量ccc,答案即位最大流
考虑dp求最小割,有
dpi,j=min(dpi−1,j−1+pi,dpi−1,j+si+c∗j)dp_{i,j}=min(dp_{i-1,j-1}+p_i,dp_{i-1,j}+s_i+c*j)dpi,j=min(dpi−1,j−1+pi,dpi−1,j+si+c∗j)
我们发现
割集每多包含一个节点i,容量增加pi−si+c∗(i−k)p_i-s_i+c*(i-k)pi−si+c∗(i−k),k为割集中已有点数,我们可以将k分离变量,令wi=pi−si+c∗iw_i=p_i-s_i+c*iwi=pi−si+c∗i,每次把最小的wiw_iwi加入点集,和答案取最小值
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <functional>
#include <cstdlib>
#include <queue>
#include <stack>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define MAXN (123456)
ll n,c;
ll a[MAXN];
priority_queue<ll> q;
int main() {
// freopen("B.in","r",stdin);
scanf("%lld%lld",&n,&c);
ll tot=0;
For(i,n) scanf("%lld",&a[i]),tot+=a[i];
For(i,n) {
q.push(a[i]-read()-(ll)c*(n-i));
}
ll ans=tot;
For(i,n) {
tot-=q.top()+c*(i-1);
ans=min(ans,tot);
q.pop();
}
cout<<ans<<endl;
return 0;
}