点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ls rt<<1
#define rs (rt<<1|1)
const int N=1e6+5;
int T,n,len;
int m,c,ans;
int a[N],b[N],tlsh[N],s[N],use[N];
priority_queue<int>q;
struct node{
int x,id;
}lsh[N];
bool cmp(node x,node y){return x.x<y.x;}
struct node1{
int min,lz;
}tr[N<<2];
void pushup(int rt) {tr[rt].min=min(tr[ls].min,tr[rs].min);}
void pushdown(int rt)
{
if(!tr[rt].lz) return ;
tr[ls].min+=tr[rt].lz;
tr[rs].min+=tr[rt].lz;
tr[ls].lz+=tr[rt].lz;
tr[rs].lz+=tr[rt].lz;
tr[rt].lz=0;
}
void build(int rt,int l,int r)
{
tr[rt].min=tr[rt].lz=0;
if(l==r) return tr[rt].min=s[l-1]-use[l],void();
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
pushup(rt);
}
void update(int rt,int l,int r,int L,int R,int val)
{
if(l>=L&&r<=R)
{
tr[rt].min+=val;
tr[rt].lz+=val;
return ;
}
int mid=(l+r)>>1;
pushdown(rt);
if(L<=mid) update(ls,l,mid,L,R,val);
if(R>mid) update(rs,mid+1,r,L,R,val);
pushup(rt);
}
int query(int rt,int l,int r,int L,int R)
{
if(l>=L && r<=R) return tr[rt].min;
pushdown(rt);
int mid=(l+r)>>1;
int ans=1e18;
if(L<=mid) ans=min(ans,query(ls,l,mid,L,R));
if(R>mid) ans=min(ans,query(rs,mid+1,r,L,R));
return ans;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin >>T;
while(T--)
{
cin >>n>>m>>c;
while(!q.empty()) q.pop();
ans=0;
for(int i=1;i<=n;i++)
{
cin >>a[i];
ans+=a[i];
}
for(int i=1;i<=n;i++) cin >>b[i];
s[0]=m;
for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i]/c;
int minn=1e18;
for(int i=n;i>=1;i--)
{
minn=min(minn,s[i-1]);
int cnt=min(min(b[i],minn),a[i]%c);
use[i]=cnt;
minn-=cnt;
}
for(int i=1;i<=n;i++) s[i]=s[i-1]-use[i]+a[i]/c;
minn=1e18;
for(int i=n;i>=1;i--)
{
int cnt=min(min((b[i]-use[i])/c,minn/(c+1)),(s[i-1]-use[i])/c);
use[i]+=cnt*c;
minn-=cnt*(c+1);
minn=min(minn,s[i-1]-use[i]);
}
for(int i=1;i<=n;i++) s[i]=s[i-1]-use[i]+(a[i]-use[i])/c;
build(1,1,n);
for(int i=1;i<=n;i++)
{
lsh[i]={b[i]-use[i],i};
tlsh[i]=b[i]-use[i];
}
sort(lsh+1,lsh+1+n,cmp);
sort(tlsh+1,tlsh+1+n);
len=unique(tlsh+1,tlsh+n+1)-tlsh-1;
for(int i=len,j=n;i>=1;i--)
{
while(j>=1 && lsh[j].x>=tlsh[i])
{
q.push(lsh[j].id);
j--;
}
while(!q.empty())
{
int d=q.top();
int min1=query(1,1,n,d,d),min2=(d==n?1e18:query(1,1,n,d+1,n)-1);
int cnt=min(b[d]-use[d],min(min1,min2));
if(cnt>=tlsh[i-1])
{
q.pop();
use[d]+=cnt;
update(1,1,n,d,d,-cnt);
if(d<n) update(1,1,n,d+1,n,-cnt-1);
}
else break;
}
}
for(int i=1;i<=n;i++) ans-=use[i];
cout <<ans<<'\n';
}
}