题意:长度为n的序列A,B.操作:选定一个区间[L,R]将里面的数变为h , h<=min(a[L],a[L+1]...a[R]).
n<=1e5,1<=a[i],b[i]<=1e9. 问将序列A变为序列B最少需要多少次操作? 无解输出-1.
假设某次操作是将[L,R]内的数变为x.
则x要满足 max(b[i]) <= x <= min(a[i]) i=[L...R].
因为最多操作n次. 所以每一次操作[L,R,x] 这个x肯定等于某个 b[i] i=[L;R].
同样的某个点i.最后肯定会被某个[L,R,b[i]]操作到.
令val=b[1] b[1]前面没有操作,显然我们想让后面更多b[j]=val被这一次操作到.
用一个单调队列来维护,队列中的元素x表示操作为[L,R,x]的可以进行到当前i.
若b[i]>b[j] 则队列中的b[j]显然不能在往后面操作.
若b[front]>a[i] a[i]不能变高,队头元素也不能往后操作.
此时若b[i]!=b[rear] 则当前位置要想变成b[i]必须新增一个操作(前面[l,r,x]的操作不可能跨到位置i)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
int T,n,a[N],b[N];
int main(){
ios::sync_with_stdio(false);cin.tie(0);
cin>>T;
while(T--){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
bool flag=true;
for(int i=1;i<=n;i++) if(a[i]<b[i]) flag=false;
if(!flag){
cout<<-1<<'\n';
continue;
}
deque<int> q;
int res=0;
for(int i=1;i<=n;i++){
while(!q.empty()&&b[i]>q.back()) q.pop_back();
while(!q.empty()&&a[i]<q.front()) q.pop_front();
if(a[i]!=b[i]&&(q.empty()||b[i]!=q.back())){
res++;
q.push_back(b[i]);
}
}
cout<<res<<'\n';
}
return 0;
}