zoukankan      html  css  js  c++  java
  • 【bzoj4059】[Cerc2012]Non-boring sequences 分治

    题目描述

    我们害怕把这道题题面搞得太无聊了,所以我们决定让这题超短。一个序列被称为是不无聊的,仅当它的每个连续子序列存在一个独一无二的数字,即每个子序列里至少存在一个数字只出现一次。给定一个整数序列,请你判断它是不是不无聊的。

    输入

    第一行一个正整数T,表示有T组数据。每组数据第一行一个正整数n,表示序列的长度,1 <= n <= 200000。接下来一行n个不超过10^9的非负整数,表示这个序列。

    输出

    对于每组数据输出一行,输出"non-boring"表示这个序列不无聊,输出"boring"表示这个序列无聊。

    样例输入

    4
    5
    1 2 3 4 5
    5
    1 1 1 1 1
    5
    1 2 3 2 1
    5
    1 1 2 1 1

    样例输出

    non-boring
    boring
    non-boring
    boring


    题解

    分治

    考虑一段区间:

    如果这个区间中存在某个数,使得它在整段区间中出现次数为1,那么对于所有包含该数的子区间,该数都出现且仅出现1次。所以只需要分治处理这个数左右两端的子区间即可。

    如果这个区间中不存在这样的数,那么它就是不合法的。

    于是只需要想办法求出区间中只出现过一次的数即可。一个数在区间中只出现过1次,当且仅当它上一次出现的位置在区间左端,下一次出现的位置在区间右端。所以预处理左右出现的位置即可判断。

    由于这个数不是恰好出现在区间中间的,所以找一次的时间复杂度应该设计为$O(较小的一段子区间的长度)$。具体方法:从左右两端向中间扫,扫到了就停止。这样找一次的复杂度一定是2倍较短区间长度。

    时间复杂度为$O(nlog n)$。

    注意由于有多组数据,数组需要动态清空,不能使用memset。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 200010
    using namespace std;
    int a[N] , v[N] , pos[N] , lp[N] , rp[N];
    bool solve(int l , int r)
    {
        if(l > r) return 1;
        int i , mid = 0;
        for(i = l ; i <= (l + r) >> 1 ; i ++ )
        {
            if(lp[i] < l && rp[i] > r) mid = i;
            if(lp[l + r - i] < l && rp[l + r - i] > r) mid = l + r - i;
            if(mid) break;
        }
        if(mid) return solve(l , mid - 1) && solve(mid + 1 , r);
        else return 0;
    }
    int main()
    {
        int T;
        scanf("%d" , &T);
        while(T -- )
        {
            int n , i;
            scanf("%d" , &n);
            for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &a[i]) , v[i] = a[i] , pos[i] = lp[i] = 0 , rp[i] = n + 1;
            sort(v + 1 , v + n + 1);
            for(i = 1 ; i <= n ; i ++ ) a[i] = lower_bound(v + 1 , v + n + 1 , a[i]) - v , lp[i] = pos[a[i]] , rp[lp[i]] = i , pos[a[i]] = i;
            if(solve(1 , n)) printf("non-");
            puts("boring");
        }
        return 0;
    }
    
    

     

  • 相关阅读:
    【搜索结果】高亮显示
    【搜索面板】排序单选
    【搜索面板】价格信息单选
    根据接口返回的数据重组数组
    Array.from
    获取指定字符串第n次出现的位置索引
    Object
    验证码倒计时
    iview Form表单正则验证
    网络图片转base64格式
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7423508.html
Copyright © 2011-2022 走看看