好序列 启发式分治

 

 

//题意:给定一个序列,如果这个序列的每个子区间都满足:至少有一个数只在这个区间内出现一次。那么这个序列称为好序列
//思路:本题可以用点分治做,这里采用的是启发式分治的做法,详情见博客
#include<bits/stdc++.h>
using namespace std;
const int N = 201000;
int a[N], n, pre[N], nxt[N];//记录序列
bool solve(int l, int r) {
    if (l > r) return true;
    for (int pl = l, pr = r; pl <= pr; pl++, pr--) {
        if (pre[pl]<l && nxt[pl]>r)
            return solve(l, pl - 1) && solve(pl + 1, r);
        if (pre[pr]<l && nxt[pr]>r)
            return solve(l, pr - 1) && solve(pr + 1, r);
    }
    return false;
}
bool solve() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    map<int, int> pos;//数字种类与该类数字最后一次出现的位置相对应
    for (int i = 1; i <= n; i++) {
        if (pos.count(a[i])) pre[i] = pos[a[i]];
        else pre[i] = 0;
        pos[a[i]] = i;
    }
    pos.clear();
    for (int i = n; i >= 1; i--) {
        if (pos.count(a[i])) nxt[i] = pos[a[i]];
        else nxt[i] = n + 1;
        pos[a[i]] = i;
    }
    return solve(1, n);
}
int main() {
    int tc;
    scanf("%d", &tc);
    for (int T = 0; T < tc; T++) {
        puts(solve() ? "non-boring" : "boring");
    }
}

 

 

 

posted @ 2022-12-31 15:00  Aacaod  阅读(21)  评论(0编辑  收藏  举报