CF1265B Beautiful Numbers
Beautiful Numbers
思维题吧?
题目大意:给出 到 的任意一个排列,对于每个 ,是否有在这个序列里面有 到 的任意一个排列。
先考虑这样的做法,显然如果包含 到 的某一个排列的话,在原序列对应的这一段的下标显然是连续的,考虑用 维护 到 的某一个排列的下标序列。每次插入一个数就判断他的左边和右边的位置差是不是 即可。时间复杂度为 。
接下来我们考虑使用双指针,也就是用 维护 到 的任意排列的数字中下标最大或者最小的某个数的位置。原因是构成 的任意排列,所以在 中的数必然都要是 的数才可以。
考虑用一个变量 维护 中和 不同的数,分情况讨论:
- 
如果当前的数出现的位置超过了 或者 ,我们就更新 或 ,同时给 加上跳过的位置,由于 的位置我们在以前维护过了,所以跳过的位置必然没有 的任何数。
 - 
如果当前的位置在 之间,那么 减一,原因显然, 中多了一个出现 的数字。
 
#include<bits/stdc++.h>
using namespace std;
const int N =1e6+10;
int a[N],t[N];
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n,l,r,lmax,rmax;
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i],t[a[i]]=i;
			if(a[i]==1)
				lmax=i,rmax=i;
		}
		int sum=0;
		cout<<1;
		for(int i=2;i<=n;i++)
		{
			if(t[i]>rmax)	sum+=(t[i]-rmax-1),rmax=t[i];
			else if(t[i]<lmax)	sum+=(lmax-t[i]-1),lmax=t[i];
			else sum--;
			if(sum==0)
				cout<<1;
			else
				cout<<0;
		}
		cout<<endl;
	}
}

                
            
        
浙公网安备 33010602011771号