D. 서브 어레이 정렬 (최소 간격 분석 유지 +)

이름

질문의 의미 :

    두 배열에 A, B. 용량이 큰 소형의 범위 중 하나를 할 수 있고, 그것은 여부 어레이 B 지도록 배열의 조작에 의해 결정된다.
     1 1 0 5 , 1 나는 , 1 b i n 1≤n≤3⋅10 ^ 5,1≤a_i≤n, 1≤b_i≤n

분석 :

    왼쪽에서 오른쪽으로 우리가 B [I]은 [I]은 [I] == B를 충족 고려는 분명히 위치를 찾아야한다 곳에 배열 x의 대응 값이 값 [1, X]이 최소 범위는, 우리는 그렇지 않으면 그를 방해하는 바인딩 요소보다 작은 경우, 이동 할 수 있습니다. 이유는 [X 1]인가? 경기 전에 앞으로 가져 요소가 이동하기 때문에, 그 다른 구성 요소가 실제로 이동 일치하지 만, 모두가 위치되어 일치하지 않는이 이동 처리를 유지하지 않는,이 간격 값은 [1은 X] [I] A B 후. 당신이 그들의 존재를 고려하지 않아도, 최대로 설정 될 수 있으며, 전면에 올려 요소에 대한 좋은 경기를하고있다. 유지 보수 세그먼트 트리 클릭의 최소 간격.

#include <iostream>
#include <queue>
using namespace std;

queue<int> q[300005];
int b[300005];

struct node{
	int l,r,minx;
}a[300005*4];

void update(int x)
{
	a[x].minx = min(a[2*x].minx,a[2*x+1].minx); 
}

void build(int x,int l,int r)
{
	a[x].l = l;
	a[x].r = r;
	if( l == r )
	{
		a[x].minx = 0;
		return;
	}
	int mid = ( l + r ) / 2;
	build(2*x,l,mid);
	build(2*x+1,mid+1,r);
	update(x);
}

void change(int x,int l,int r,int k)
{
	if( a[x].l == l && a[x].r == r )
	{
		a[x].minx += k;
		return;
	}
	int mid = ( a[x].l + a[x].r ) / 2;
	if( l > mid ) change(2*x+1,l,r,k);
	else if( r <= mid ) change(2*x,l,r,k);
	else
	{
		change(2*x,l,mid,k);
		change(2*x+1,mid+1,r,k);
	}
	update(x);
}

int query(int x,int l,int r)
{
	if( a[x].l == l && a[x].r == r ) return a[x].minx;
	int mid = ( a[x].l + a[x].r ) / 2;
	if( l > mid ) return query(2*x+1,l,r);
	else if( r <= mid ) return query(2*x,l,r);
	else return min(query(2*x,l,mid),query(2*x+1,mid+1,r));
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;
	cin >> t;
	while( t-- )
	{
		int n;
		cin >> n;
		build(1,1,n);
		for (int i = 1; i <= n; i++) 
		{
			while( !q[i].empty() ) q[i].pop();
		}
		for (int i = 1; i <= n; i++)
		{
			int x;
			cin >> x;
			q[x].push(i);
			change(1,i,i,x);
		}
		for (int i = 1; i <= n; i++)
		{
			cin >> b[i];
		}
		int flag = 0;
		for (int i = 1; i <= n; i++)
		{
			//cout << i << '\n';
			if( q[b[i]].empty() )
			{
				flag = 1;
				break;
			}
			int x = q[b[i]].front();
			q[b[i]].pop();
			int t = query(1,1,x);
			//cout << "asd " << x << ' ' <<t << '\n'; 
			if( t != b[i] )
			{
				flag = 1;
				break;
			}
			change(1,x,x,3e5);
		}
		if( flag ) cout << "NO" << '\n';
		else cout << "YES" << '\n';
	}
	return 0;
}

게시 된 132 개 원래 기사 · 원 찬양 6 · 전망 7927

추천

출처blog.csdn.net/weixin_44316314/article/details/104868956