传送门
考虑一个费用流做法
S → a i ( 1 , a i ) , a i → b i ( 1 , 0 ) , b i → T ( 1 , b i ) , a i → X ( 1 , 0 ) , X → Y ( k − l , 0 ) , Y → b i ( 1 , 0 ) S\rightarrow a_i(1,a_i),a_i\rightarrow b_i(1,0),b_i\rightarrow T(1,b_i),a_i\rightarrow X(1,0),X\rightarrow Y(k-l,0),Y\rightarrow b_i(1,0) S→ai(1,ai),ai→bi(1,0),bi→T(1,bi),ai→X(1,0),X→Y(k−l,0),Y→bi(1,0)
考虑利用堆来模拟费用流
设 x , y x,y x,y间流量为 c n t cnt cnt
考虑每次增加 1 1 1的流量
那么有几种情况
S → a i → b i → T , c n t S\rightarrow a_i\rightarrow b_i\rightarrow T,cnt S→ai→bi→T,cnt不变
S → a i → X → Y → b j → T , c n t + 1 S\rightarrow a_i\rightarrow X \rightarrow Y\rightarrow b_j\rightarrow T,cnt+1 S→ai→X→Y→bj→T,cnt+1
S → a i → b i → Y → X → a j → b j → T , c n t − 1 S\rightarrow a_i\rightarrow b_i\rightarrow Y\rightarrow X\rightarrow a_j \rightarrow b_j \rightarrow T,cnt-1 S→ai→bi→Y→X→aj→bj→T,cnt−1
S → a i → b i → Y → b j , c n t S\rightarrow a_i\rightarrow b_i\rightarrow Y\rightarrow b_j,cnt S→ai→bi→Y→bj,cnt不变
S → a i → X → a j → b j , c n t S\rightarrow a_i\rightarrow X\rightarrow a_j\rightarrow b_j,cnt S→ai→X→aj→bj,cnt不变
于是用五个堆堆维护 a i + b i , a i , b i ( a i , b i 都 没 被 选 ) a_i+b_i,a_i,b_i(a_i,b_i都没被选) ai+bi,ai,bi(ai,bi都没被选), a i , b i ( b i / a i 已 经 被 选 了 的 最 大 值 ) a_i,b_i(b_i/a_i已经被选了的最大值) ai,bi(bi/ai已经被选了的最大值)
即可
复杂度 O ( n l o g n ) O(nlogn) O(nlogn)
#include
using namespace std;
#define cs const
#define re register
#define pb push_back
#define pii pair
#define ll long long
#define fi first
#define se second
#define bg begin
cs int RLEN=1<<20|1;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
inline int read(){
char ch=gc();
int res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline ll readll(){
char ch=gc();
ll res=0;bool f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
inline int readstring(char *s){
int top=0;char ch=gc();
while(isspace(ch))ch=gc();
while(!isspace(ch)&&ch!=EOF)s[++top]=ch,ch=gc();
return top;
}
template<class tp>inline void chemx(tp &a,tp b){
a<b?a=b:0;}
template<class tp>inline void chemn(tp &a,tp b){
a>b?a=b:0;}
cs int N=200005;
struct node{
int s,id;
node(int _a=0,int _b=0):s(_a),id(_b){
}
friend inline bool operator <(cs node &a,cs node &b){
return a.s<b.s;
}
};
priority_queue<node>ab,a,b,fa,fb;
int n,k,l,A[N],B[N],va[N],vb[N];
inline void clear(){
memset(va,0,sizeof(va)),memset(vb,0,sizeof(vb));
while(a.size())a.pop();
while(b.size())b.pop();
while(ab.size())ab.pop();
while(fa.size())fa.pop();
while(fb.size())fb.pop();
}
inline void solve(){
node INF=node(-1e9,0);
int cnt=0;ll res=0;
n=read(),k=read(),l=read();
for(int i=1;i<=n;i++)A[i]=read();
for(int i=1;i<=n;i++)B[i]=read();
for(int i=1;i<=n;i++)ab.push(node(A[i]+B[i],i)),a.push(node(A[i],i)),b.push(node(B[i],i));
for(int i=1;i<=k;i++){
node v1,v2,v3,v4,v5;
v1=ab.size()?ab.top():INF;
v2=a.size()?a.top():INF;
v3=b.size()?b.top():INF;
v4=fa.size()?fa.top():INF;
v5=fb.size()?fb.top():INF;
if(((cnt==k-l||v1.s>=v2.s+v3.s)&&(v1.s>=v2.s+v5.s&&v1.s>=v3.s+v4.s&&v1.s>=v4.s+v5.s))){
res+=v1.s,va[v1.id]=vb[v1.id]=1;
}
else if(v2.s>v4.s&&v3.s>v5.s&&cnt<k-l){
res+=v2.s+v3.s,va[v2.id]=vb[v3.id]=1;
fb.push(node(B[v2.id],v2.id)),fa.push(node(A[v3.id],v3.id));
cnt++;
}
else if(v5.s>v3.s&&v4.s>v2.s){
res+=v4.s+v5.s,va[v4.id]=vb[v5.id]=1;
cnt--;
}
else if(v4.s+v3.s>v2.s+v5.s){
res+=v4.s+v3.s,va[v4.id]=vb[v3.id]=1,fa.push(node(A[v3.id],v3.id));
}
else {
res+=v2.s+v5.s,va[v2.id]=vb[v5.id]=1,fb.push(node(B[v2.id],v2.id));
}
while(ab.size()&&(va[ab.top().id]||vb[ab.top().id]))ab.pop();
while(a.size()&&(va[a.top().id]||vb[a.top().id]))a.pop();
while(b.size()&&(va[b.top().id]||vb[b.top().id]))b.pop();
while(fa.size()&&(va[fa.top().id]||!vb[fa.top().id]))fa.pop();
while(fb.size()&&(!va[fb.top().id]||vb[fb.top().id]))fb.pop();
}
cout<<res<<'\n';
clear();
}
int main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
int T=read();
while(T--)solve();
return 0;
}