题目链接:http://codeforces.com/contest/1450/problem/D
D. Rating Compression
On the competitive programming platform CodeCook, every person has a rating graph described by an array of integers a of length n. You are now updating the infrastructure, so you’ve created a program to compress these graphs.
The program works as follows. Given an integer parameter k, the program takes the minimum of each contiguous subarray of length k in a.
More formally, for an array a of length n and an integer k, define the k-compression array of a as an array b of length n−k+1, such that
bj=minj≤i≤j+k−1ai
For example, the 3-compression array of [1,3,4,5,2] is [min{1,3,4},min{3,4,5},min{4,5,2}]=[1,3,2].
A permutation of length m is an array consisting of m distinct integers from 1 to m in arbitrary order. For example, [2,3,1,5,4] is a permutation, but [1,2,2] is not a permutation (2 appears twice in the array) and [1,3,4] is also not a permutation (m=3 but there is 4 in the array).
A k-compression array will make CodeCook users happy if it will be a permutation. Given an array a, determine for all 1≤k≤n if CodeCook users will be happy after a k-compression of this array or not.
Input
The first line contains a single integer t (1≤t≤104) — the number of test cases.
The first line of the description of each test case contains a single integer n (1≤n≤3⋅105) — the length of the array.
The second line of the description of each test case contains n integers a1,…,an (1≤ai≤n) — the elements of the array.
It is guaranteed, that the sum of n for all test cases does not exceed 3⋅105.
Output
For each test case, print a binary string of length n.
The k-th character of the string should be 1 if CodeCook users will be happy after a k-compression of the array a, and 0 otherwise.
Example
input
5
5
1 5 3 4 2
4
1 3 2 1
5
1 3 3 3 2
10
1 2 3 4 5 6 7 8 9 10
3
3 3 2
output
10111
0001
00111
1111111111
000
Note
In the first test case, a=[1,5,3,4,2].
- The 1-compression of a is [1,5,3,4,2] and it is a permutation.
- The 2-compression of a is [1,3,3,2] and it is not a permutation,since 3 appears twice.
- The 3-compression of a is [1,3,2] and it is a permutation.
- The 4-compression of a is [1,2] and it is a permutation.
- The 5-compression of a is [1] and it is a permutation.
题意大意:
给你一个长度为n的数组a,一个定义bj = min(ai) (j≤i≤j+k−1),k表示将数组a分为连续的长度为k的小段,k的值可以从1到n。当k=1的时, b1 = a1,b2 = a2……k=2的时, b1 = min(a1,a2),b2 = min(a2,a3)……判断b数组若不是由1到n-k+1的数字组成的排列,那么就输出0,否则就输出1。
思路:
- 首先特判一下当k=1和n时的答案,当k=1时,显然只有1到n的每个数字都出现一次才能输出1,否则输出0。当k=n时,显然只有当存在数字1才能输出1,否则输出0。
- 接下来我们进行假设,如果将最小的数放在序列的中间位置,必然会使一些段的最小值连续出现这个最小的数,显然应该把此最小的数放在序列的两端。所以可以维护一个双端队列进行判断,从1到n进行遍历,将小的数字依次放在双端队列的左右两端,并且小于n-k+1的数字的个数必须都为1,否则会出现上述使一些段的最小值连续出现某一最小值的现象,而等于n-k+1的数字的个数只要大于0即可。满足上述的则输出1,否则输出0。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
int ans[maxn],a[maxn],cnt[maxn];
int main()
{
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(ans,0,sizeof(ans));
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
cnt[a[i]]++;
}
bool flag=1;
for(int i=1;i<=n;i++){
if(cnt[i]>1) flag=0;
}
if(flag) ans[1]=1;
if(cnt[1]) ans[n]=1;
int l=1,r=n,cur=1;
for(int i=n-1;i>=2;i--){
if(cnt[cur+1]&&cnt[cur]==1&&(a[l]==cur||a[r]==cur)){
ans[i]=1;
if(a[l]==cur)
l++;
else
r--;
++cur;
}
else break;
}
for(int i=1;i<=n;i++) printf("%d",ans[i]);
puts("");
}
}