• 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
  • 相关阅读:
    Thinkphp回顾(五)之前台模板中的基本语法
    Thinkphp回顾之(四)查询方法深入学习
    Thinkphp框架回顾(三)之怎么实现平常的sql操作数据库
    Thinkphp学习回顾(二)之config.php的配置
    Thinkphp学习回顾(一)之基本结构目录
    端口
    curl put delete post get请求类型参数
    xshell连接virtualbox下的linux系统
    实现jsonp的三种方式
    匹配汉字
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj4059.html
Copyright © 2020-2023  润新知