cf1494C
首先题目中的箱子只能往一个方向推,因此正负的解决方法是一样的。
当我们一个个向前推箱子的时候,我们不妨把一个个相接的箱子想象成火车的车厢,把特殊的位置想做站台,然后在刚开始会有一些车厢位于站台,然后题目就可以转化为最多有多少车厢可以同时听到站台。
别问我为什么站台只能放一个车厢
这样我们可以首先求出恰好在站台的车箱数,然后从前往后枚举车站,即火车头恰好到达这个车站,并求出当前火车的长度,及当前车厢可以覆盖的站台数,这个站台数分为两部分,一个是正在向右移的列车所占据的站台数,一个是还未合并但未在站台的车厢数,均可以线性求出。至此复杂度为\(O(n+m)\)
int T;
vector<int>al,ar,bl,br;
map<int,int>s,ss;
int solve(vector<int> &a,vector<int> &b){
if(a.size()==1||b.size()==1) return 0;
int n=a.size()-1,m=b.size()-1;
s.clear();ss.clear();
int sum=0,ans=0;
rep(i,1,n) ss[a[i]]=1;
rep(i,1,m) {
if(ss[b[i]])s[b[i]]=1,sum++;
}
int l=1,pos=0;
ans=sum;
rep(i,1,m){
if(s[b[i]]) sum--;
while(a[pos+1]<=b[i]&&pos<n) pos++;
while(b[i]-pos+1>b[l]) l++;
ans=max(ans,i-l+1+sum);
}
return ans;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in0.txt","r",stdin);
// freopen("2.out","w",stdout);
#endif
T=read();
while(T--){
int tmp;int n,m;
al.clear(),ar.clear();
bl.clear();br.clear();
al.pb(0);ar.pb(0);
bl.pb(0);br.pb(0);
n=read(),m=read();
rep(i,1,n){
tmp=read();
if(tmp<0) al.pb(-tmp);
else ar.pb(tmp);
}
rep(j,1,m) {
tmp=read();
if(tmp<0) bl.pb(-tmp);
else br.pb(tmp);
}
int a;
reverse(al.begin()+1,al.end());
reverse(bl.begin()+1,bl.end());
print(solve(al,bl)+solve(ar,br));pts;
}
return 0;
}