Description
Solution
猜想:假如满足条件的k的最小值(除1以外) 为 x, 那么大于等于x的k值都满足条件
证明:待补
用单调栈check的二分来找到这个最小值x
时间复杂度: O ( N ∗ log N ) O(N * \log N) O(N∗logN)
Code
const ll inf = 2e18 + 7;
const int maxn = 3e5 + 7;
int n, a[maxn];
int head, tail,que[maxn];
bool vis[maxn];
bool check(int d) {
head = tail = 0;
for(int i = 1;i <= n;++i) vis[i] = false;
for(int i = n;i >= 1;--i) {
while(head < tail && a[i] < a[que[tail-1]]) tail--;
que[tail++] = i;
while(head < tail && que[head] - que[tail-1] + 1 > d) head++;
if(i + d - 1 > n) continue;
int tmp = a[que[head]];
if(vis[tmp]) return false;vis[tmp] = true;
}
for(int i = 1;i <= n - d + 1;++i) {
if(!vis[i]) return false;
}return true;
}
int main() {
int T;scanf("%d",&T);
while(T--) {
scanf("%d",&n);
for(int i = 1;i <= n;++i) scanf("%d",&a[i]);
int l = 2, r = n, mid, ans = inf;
while(l <= r) {
mid = (l + r) >> 1;
if(check(mid)) {ans = mid;r = mid - 1;}
else l = mid + 1;
}
if(check(1)) printf("1"); else printf("0");
for(int i = 2;i <= n;++i) {
if(i >= ans) printf("1"); else printf("0");
}printf("\n");
}
return 0;
}