D. Subarray Sorting
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given an array a1,a2,…,ana1,a2,…,an and an array b1,b2,…,bnb1,b2,…,bn.
For one operation you can sort in non-decreasing order any subarray a[l…r]a[l…r] of the array aa.
For example, if a=[4,2,2,1,3,1]a=[4,2,2,1,3,1] and you choose subbarray a[2…5]a[2…5], then the array turns into [4,1,2,2,3,1][4,1,2,2,3,1].
You are asked to determine whether it is possible to obtain the array bb by applying this operation any number of times (possibly zero) to the array aa.
Input
The first line contains one integer tt (1≤t≤3⋅1051≤t≤3⋅105) — the number of queries.
The first line of each query contains one integer nn (1≤n≤3⋅1051≤n≤3⋅105).
The second line of each query contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤n1≤ai≤n).
The third line of each query contains nn integers b1,b2,…,bnb1,b2,…,bn (1≤bi≤n1≤bi≤n).
It is guaranteed that ∑n≤3⋅105∑n≤3⋅105 over all queries in a test.
Output
For each query print YES (in any letter case) if it is possible to obtain an array bb and NO (in any letter case) otherwise.
Example
input
Copy
4
7
1 7 1 4 4 5 6
1 1 4 4 5 7 6
5
1 1 3 3 5
1 1 3 3 5
2
1 1
1 2
3
1 2 3
3 2 1
output
Copy
YES
YES
NO
NO
Note
In first test case the can sort subarray a1…a5a1…a5, then aa will turn into [1,1,4,4,7,5,6][1,1,4,4,7,5,6], and then sort subarray a5…a6a5…a6.
題意,給t,n, a[i] b[i] 能否通過對a數組進行部分排序(從小到大)得到b數組
做法:我不會,看許老師的做法補的題
線段樹查詢區間最小值,點更新。如何找到第一個等於bi的位置k呢?
類似分塊,把i放到b[i]的隊列裏去。
原理大概就是 若b[i]第一個出現的位置k,1到k當中有比b[i]小的話(該小值之前未清空,這個小值就會在b數組中的b【i】這個位置的後面出現),那麼無論怎麼排,都不可能構造出b數組。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define per(i,a,b) for(int i=a;i>=(b);--i)
#define in(x) scanf("%d",&x)
#define ind(x) scanf("%lld",&x)
#define out(x) printf("%d ",x);
#define outln(x) printf("%lld\n",x);
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
#define PE(x,y) x=((x)+(y))%mod
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
ll powmod(ll a,ll b) {ll res=1;a%=mod;
for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
const int N=3e5+10,inf=0x3f3f3f3f;
int sum[N*4],n;
int a[N],b[N];
int idd,minum;
queue<int>que[N];
void build(int id,int l,int r){
if(l==r){
in(sum[id]);
que[sum[id]].push(l);
return ;
}
int mid=l+r>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
sum[id]=min(sum[id<<1],sum[id<<1|1]);
}
int qu(int id,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr){
return sum[id];
}
int mi=inf;
int mid=l+r>>1;
if(ql<=mid) mi=min(mi,qu(id<<1,l,mid,ql,qr));
if(qr>mid) mi=min(mi,qu(id<<1|1,mid+1,r,ql,qr));
return mi;
}
void up(int id,int l,int r,int pos){
if(l==r){
//printf("old:%d new:%d l:%d pos:%d\n",sum[id],inf,l,pos);
sum[id]=inf;
return ;
}
int mid=l+r>>1;
if(pos<=mid) up(id<<1,l,mid,pos);
else up(id<<1|1,mid+1,r,pos);
sum[id]=min(sum[id<<1],sum[id<<1|1]);
}
int main()
{
int _;
cin>>_;
while(_--){
in(n);
for(int i=1;i<=n;i++) {
while(que[i].size()) que[i].pop();
}
build(1,1,n);
rep(i,1,n) in(b[i]);
bool flag=1;
for(int i=1;i<=n;i++){
if(!que[b[i]].empty()){
int idd=que[b[i]].front();
que[b[i]].pop();
int minum=qu(1,1,n,1,idd);
if(minum<b[i]){
flag=0;
break;
}
else up(1,1,n,idd);
}
else{
flag=0;
break;
}
}
if(flag) printf("YES\n");
else printf("NO\n");
}
}