CF1187D. Subarray Sorting

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.

 

对应第一个数组从左往右开始的每一个数。移动第二个数组对应的某一个数(最前面相同的数)。想象一步一步的往前移(贪心思想,本题的关键),能尽量保留其它数的顺序关系。当第二个数组的某一个数能移动到第一个数组中的某一个数时,要当前第二个数组前面的数都大于它。所以用到线段树保存区间最小值。

import java.util.*;
import java.io.*;

public class Main {
	public static void main(String args[]) {new Main().run();}

	FastReader in = new FastReader();
	PrintWriter out = new PrintWriter(System.out);
	void run(){
		int q=ni();
		for(int i=0;i<q;i++) {
			work();
		}
		out.flush();
	}
	long mod=1000000007;
	long gcd(long a,long b) {
		return a==0?b:gcd(b%a,a);
	}
	
	int[] M;
	LinkedList<Integer>[] queues;
	int[] A,B;
	void work() {
		int n=ni();
		A=nia(n);
		B=nia(n);
		M=new int[n<<2];
		queues=(LinkedList<Integer>[])new LinkedList[n+1];
		for(int i=0;i<=n;i++) {
			queues[i]=new LinkedList<>();
		}
		for(int i=0;i<n;i++) {
			queues[A[i]].add(i);
		}
		for(int i=0;i<n;i++) {
			update(1,0,n-1,i,A[i]);
		}
		
		for(int i=0;i<n;i++) {
			int num=B[i];
			if(queues[num].size()==0) {
				out.println("NO");
				return;
			}
			int idx=queues[num].poll();
			int v=query(1,0,n-1,0,idx);
			if(v!=num) {
				out.println("NO");
				return;
			}
			update(1,0,n-1,idx,999999999);
		}
		out.println("YES");
	}

	
	
	private int query(int idx, int l, int r, int s, int e) {
		if(l>=s&&r<=e) {
			return M[idx];
		}
		int m=l+(r-l)/2;
		int ret=999999999;
		if(m>=s) {
			ret=Math.min(ret,query(idx<<1,l,m,s,e));
		}
		if(m+1<=e) {
			ret=Math.min(ret,query(idx<<1|1,m+1,r,s,e));
		}
		return ret;
	}



	private void update(int idx, int l, int r, int x, int v) {
		if(l==r) {
			M[idx]=v;
			return;
		}
		int m=l+(r-l)/2;
		if(x<=m) {
			update(idx<<1,l,m,x,v);
		}else {
			update(idx<<1|1,m+1,r,x,v);
		}
		M[idx]=Math.min(M[idx<<1], M[idx<<1|1]);
	}

	

	//input
	private ArrayList<Integer>[] ng(int n, int m) {
		ArrayList<Integer>[] graph=(ArrayList<Integer>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			int s=in.nextInt()-1,e=in.nextInt()-1;
			graph[s].add(e);
			graph[e].add(s);
		}
		return graph;
	}

	private ArrayList<long[]>[] ngw(int n, int m) {
		ArrayList<long[]>[] graph=(ArrayList<long[]>[])new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i]=new ArrayList<>();
		}
		for(int i=1;i<=m;i++) {
			long s=in.nextLong()-1,e=in.nextLong()-1,w=in.nextLong();
			graph[(int)s].add(new long[] {e,w,i});
			graph[(int)e].add(new long[] {s,w});
		}
		return graph;
	}

	private int ni() {
		return in.nextInt();
	}

	private long nl() {
		return in.nextLong();
	}
	
	private String ns() {
		return in.next();
	}

	private long[] na(int n) {
		long[] A=new long[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextLong();
		}
		return A;
	}
	private int[] nia(int n) {
		int[] A=new int[n];
		for(int i=0;i<n;i++) {
			A[i]=in.nextInt();
		}
		return A;
	}
}	

class FastReader
{
	BufferedReader br;
	StringTokenizer st;

	public FastReader()
	{
		br=new BufferedReader(new InputStreamReader(System.in));
	}


	public String next() 
	{
		while(st==null || !st.hasMoreElements())//回车,空行情况
		{
			try {
				st = new StringTokenizer(br.readLine());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return st.nextToken();
	}

	public int nextInt() 
	{
		return Integer.parseInt(next());
	}

	public long nextLong()
	{
		return Long.parseLong(next());
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值