Educational Codeforces Round 67 (Rated for Div. 2) D. Subarray Sorting(线段树+思维)(*)

题目链接
在这里插入图片描述
题意:给定数组a和b,你可以在a数组里选择一个区间【l,r】,将【l,r】内的数进行sort(从小到大),问a数组最终能否通过若干次上述操作变成b数组。
思路:很有意思的题,我们着重要思考的是什么时候会不存在答案,有一点我们可以观察到,如果a是3 7 2,b数组是7 3 2的话,我们发现a数组里的7最终肯定是不可能跑到3前面去的,往这个方面仔细思考一下,以b数组为基准,首先我们将a数组建线段树,然后再把b数组建到线段树中(把a数组覆盖掉),线段树维护区间最小值,所以要把a数组覆盖掉的话就取n+1(这个操作其实就相当于把a数组给删除),然后对于b【i】来说,b【1,i-1】里的数我们都在线段树里删除掉了(相当于将那些点update成n+1),对于剩下的来说,假设b【i】在a数组里的下标为pos,那么线段树中【1,pos】的最小值如果小于b【i】的话就相当于在b【i+1,n】中还存着比b【i】还小的数x,而x在a数组里又在pos前面,就跟我上面举例的3和7一样,这样的话无论怎样sort都无法实现相等。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e5+1;
struct node{
	int l,r,minn;
}tree[maxn<<2];
vector<int>pos[maxn];
int a[maxn],b[maxn],cnt[maxn];
void pushup(int x)
{
	tree[x].minn=min(tree[x<<1].minn,tree[x<<1|1].minn);
}
void build(int x,int l,int r)
{
	tree[x].l=l;tree[x].r=r;
	if(l==r)
	{
		tree[x].minn=a[l];return ;
	}
	int mid=(l+r)>>1;
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	pushup(x);
}
void update(int x,int pos,int k)
{
	if(tree[x].l==tree[x].r) {tree[x].minn=k;return ;}
	int mid=(tree[x].l+tree[x].r)>>1;
	if(pos<=mid) update(x<<1,pos,k);
	else update(x<<1|1,pos,k);
	pushup(x);
}
int query(int x,int l,int r)
{
	if(l<=tree[x].l&&tree[x].r<=r) return tree[x].minn;
	int mid=(tree[x].l+tree[x].r)>>1;
	int ans=0x3f3f3f3f;
	if(l<=mid) ans=min(ans,query(x<<1,l,r));
	if(mid<r)  ans=min(ans,query(x<<1|1,l,r));
	return ans;
}
bool slove(int n)
{
	for(int i=1;i<=n;++i)
	{
		int size=pos[b[i]].size();
		if(size<=cnt[b[i]]) return false;
		int k=pos[b[i]][cnt[b[i]]++];
		if(query(1,1,k)<b[i]) return false;
		update(1,k,n+1);
	}
	return true;
}
int main()
{
	int T,n;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(int i=0;i<=n;++i) pos[i].clear(),cnt[i]=0;
		for(int i=1;i<=n;++i) 
		{
			scanf("%d",&a[i]);
			pos[a[i]].push_back(i);
		}
		build(1,1,n);
		for(int i=1;i<=n;++i) scanf("%d",&b[i]);
		printf("%s\n",slove(n)?"YES":"NO"); 
	}
}
发布了391 篇原创文章 · 获赞 1 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/105476110