对线性规划这一套还是不熟练。
首先我们发现单点只能减不能加,因此肯定是先变成一个局面然后剩下全部单点修改。因此想要让单点的尽量少,也就是整行/列修改的尽量多。
设\(x_i\)表示第\(i\)行能减的次数,\(y_j\)表示第\(j\)列能减的次数,对于每个\(i,j\)要满足\(x_i+y_j\leq c_{i,j}\),并且要让\(\sum\limits_{i=1}^{n}{x_i+y_i}\)最大。
发现这个东西和KM算法要求的东西极其相似,只是不等号方向反了一反。因此就是最小权完美匹配。
这个显然是\(a,b\)都排序以后按位匹配即可。
时间复杂度\(O(n\log n)\),瓶颈在排序。
code:
#include<bits/stdc++.h>
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
#define Mc(x,y) memcpy(x,y,sizeof(x))
#define d(x,y) ((m)*(x-1)+(y))
#define R(n) (rnd()%(n))
#define Pc(x) putchar(x)
#define LB lower_bound
#define UB upper_bound
#define PB push_back
using ll=long long;using db=double;using lb=long db;using ui=unsigned;using ull=unsigned ll;
using namespace std;const int N=3e5+5,M=10+5,K=1e5+5,mod=1e9+7,Mod=mod-1,INF=2e9+7;const db eps=1e-5;mt19937 rnd(263082);
int n,m,k,x,y,z,A[N],B[N];ll Ans,Ts,Q[N];
int main(){
freopen("1.in","r",stdin);
int i,j;scanf("%d",&n);for(i=1;i<=n;i++) scanf("%d",&A[i]);for(i=1;i<=n;i++) scanf("%d",&B[i]);
sort(A+1,A+n+1);sort(B+1,B+n+1);for(i=1;i<=n;i++) Q[i]=Q[i-1]+B[i];for(i=1;i<=n;i++){
int p=LB(B+1,B+n+1,A[i])-B-1;Ans+=1ll*p*A[i]-Q[p]+Q[n]-Q[p]-1ll*(n-p)*A[i];
}for(i=1;i<=n;i++) Ts+=abs(A[i]-B[i]);printf("%lld\n",Ans-Ts*(n-1));
}
标签:Hero,int,ll,db,long,Zero,CF1765J,using,define
From: https://www.cnblogs.com/275307894a/p/16989093.html