bzoj4059 [Cerc2012]Non-boring sequences

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4059

【题解】

考虑分治。定义过程solve(l,r)为判断全在[l,r]范围内的所有连续子序列是不是non-boring的

那么我们预处理每个地方的前一个与它相同的数pre[i]和后一个与它相同的数nxt[i]。

显然对于i属于[l,r],如果存在pre[i]<l,nxt[i]>r,那么任何经过i的连续子序列都合法,所以就分成[l,i-1]和[i+1,r]检测即可。

为了保证复杂度,我们要从两边同时往中间搜,这样复杂度为

T(n) = max{T(n-k) + T(k) + O(min(k, n-k))} = O(nlogn)

或者用“启发式合并”的逆过程也能证明。

# include <stdio.h>
# include <algorithm>
# include <vector>
// # include <bits/stdc++.h>
 
using namespace std;
 
int T, n, a[200010], pre[200010], nxt[200010];
int lst[200010], na[200010];
vector<int> vec;
vector<int>::iterator it;
 
inline bool judge(int l, int r) {
    if (l == r) return 1;
    if (l == r-1) return a[l] != a[r];
    for (int i=l, j=r; i<=j; ++i, --j) {
        if(pre[i] < l && nxt[i] > r) {
            if(i != l) return judge(l, i-1) && judge(i+1, r);
            else return judge(i+1, r);
        }
        if(pre[j] < l && nxt[j] > r) {
            if(j != r) return judge(l, j-1) && judge(j+1, r);
            else return judge(l, j-1);
        }
    }
    return 0;
}
 
inline void out(int *ot, int ed) {
    for (int i=1; i<=ed; ++i) printf("%d ", ot[i]);
    puts("");
}
 
int main() {
    scanf("%d", &T);
    while(T--) {
        vec.clear();
        scanf("%d", &n);
        for (int i=1; i<=n; ++i) {
            scanf("%d", &a[i]);
            pre[i] = 0, nxt[i] = n+1;
            vec.push_back(a[i]);
        }
        sort(vec.begin(), vec.end());
        it = unique(vec.begin(), vec.end());
        vec.erase(it, vec.end());
        for (int i=1; i<=n; ++i)
            na[i] = lower_bound(vec.begin(), vec.end(), a[i]) - vec.begin() + 1;
         
        for (int i=1; i<=n; ++i) lst[i] = 0;
        for (int i=1; i<=n; ++i) {
            if(lst[na[i]] != 0) pre[i]=lst[na[i]];
            lst[na[i]]=i;
        }
         
        for (int i=1; i<=n; ++i) lst[i] = n+1;
        for (int i=n; i>=1; --i) {
            if(lst[na[i]] != n+1) nxt[i]=lst[na[i]];
            lst[na[i]]=i;
        }
         
        //out(pre, n);
        //out(nxt, n);
             
        if(judge(1, n)) puts("non-boring");
        else puts("boring");
    }
 
    return 0;
}
View Code

 

posted @ 2017-06-06 16:54  Galaxies  阅读(242)  评论(0编辑  收藏  举报