Uva 1608 Non-boring sequences(分治)

来源:互联网 发布:python画一朵玫瑰花 编辑:程序博客网 时间:2024/05/17 15:06

题目地址:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4483

思路:

1.对于总序列,若p位置元素唯一,则只需判断序列[1,p-1]和序列[p+1,n]是不是无聊的(因为跨过p的序列一定不无聊,至少包含一唯一元素a[p])。

2.判断一元素在序列[l,r]中是否唯一:可以预处理出每个元素最近出现的位置,pre[i](a[i]最近的上一个位置)、nt[i](a[i]最近的下一个位置),若该元素在序列中唯一,则pre[i]<l&&nt[i]>r。

3.在序列中找到唯一元素,若只从一方向寻找(从左向右或从右向左)则最坏情况下唯一元素处在最右边或最左边,此时复杂度为n^2,若从两端向中间寻找,则最坏情况下元素位于中间,此时复杂度为nlogn 。

#include<map>#include<cstdio>#include<iostream>#include<algorithm>#define debugusing namespace std;const int maxn=200000+50;int a[maxn],n;map<int,int> cur;int pre[maxn],nt[maxn];int check(int l,int r){    if(l>=r) return true;    int x=l,y=r;    while(x<=y)    {        if(pre[x]<l&&nt[x]>r)        {            return check(l,x-1)&&check(x+1,r);        }        if(pre[y]<l&&nt[y]>r)        {            return check(l,y-1)&&check(y+1,r);        }        x++,y--;    }    return false;}int main(){#ifdef debu    freopen("in.txt","r",stdin);#endif // debug    int t;    scanf("%d",&t);    while(t--)    {        cur.clear();        scanf("%d",&n);        for(int i=1; i<=n; i++)        {            scanf("%d",&a[i]);            if(!cur.count(a[i])) pre[i]=0;            else pre[i]=cur[a[i]];            cur[a[i]]=i;        }        cur.clear();        for(int i=n; i>=1; i--)        {            if(!cur.count(a[i])) nt[i]=n+1;            else nt[i]=cur[a[i]];            cur[a[i]]=i;        }        if(check(1,n)) printf("non-boring\n");        else printf("boring\n");    }    return 0;}