• 【BZOJ4059】[Cerc2012]Non-boring sequences 分治


    【BZOJ4059】[Cerc2012]Non-boring sequences

    Description

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

    Input

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

    Output

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

    Sample Input

    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

    Sample Output

    non-boring
    boring
    non-boring
    boring

    题解:首先容易想到线段树做法,由于每个子串都是某个后缀的前缀,所以我们枚举以每个数为结尾的前缀。将这个数的权值设为1,将这个数的前驱的权值设为-1,前驱的前驱设为0,那么如果这个序列是boring的当且仅当该前缀的某个后缀权值和为0。线段树搞一搞就行。

    然后又去学了分治做法。首先[l,r]中一定要有一个只出现过一次的数,否则无解。那么所有包含这个数的区间都是不无聊的,我们只需要递归处理左右两边即可。问题是我们怎么找到这个只出现过一次的数。先预处理出前驱和后继,一个数只出现一次等价于前驱<l且后继>r。由于我们的分治不是二分,所以我们每次查找的复杂度应该是余下两个区间长度的较小值。所以我们从两端往中间一个一个找就行了。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn=200010;
    int flag,n;
    struct node
    {
    	int val,org;
    }num[maxn];
    int pre[maxn],nxt[maxn];
    bool cmp(node a,node b)
    {
    	return (a.val==b.val)?(a.org<b.org):(a.val<b.val);
    }
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    void solve(int l,int r)
    {
    	if(l>r)	return ;
    	int mid,i;
    	for(i=0;l+i<=r-i;i++)
    	{
    		if(pre[l+i]<l&&nxt[l+i]>r)
    		{
    			mid=l+i;
    			break;
    		}
    		if(pre[r-i]<l&&nxt[r-i]>r)
    		{
    			mid=r-i;
    			break;
    		}
    	}
    	if(l+i>r-i)	flag=1;
    	if(!flag)	solve(l,mid-1);
    	if(!flag)	solve(mid+1,r);
    }
    void work()
    {
    	n=rd();
    	int i;
    	for(i=1;i<=n;i++)	num[i].val=rd(),num[i].org=i,pre[i]=0,nxt[i]=n+1;
    	sort(num+1,num+n+1,cmp);
    	for(i=1;i<=n;i++)	if(num[i].val==num[i-1].val)	pre[num[i].org]=num[i-1].org,nxt[num[i-1].org]=num[i].org;
    	flag=0,solve(1,n);
    	if(flag)	printf("boring
    ");
    	else	printf("non-boring
    ");
    }
    int main()
    {
    	int T=rd();
    	while(T--)	work();
    	return 0;
    }
  • 相关阅读:
    django-搭建BBS关键点总结
    关于django中input标签中file类型以及开路由
    Bzoj1115 石子游戏Kam
    HDU1907 John
    HDU2509 Be the Winner
    洛谷P1082 同余方程
    POJ1065 Area
    Vijos1889 天真的因数分解
    Bzoj2440 完全平方数
    Bzoj2705 Longge的问题
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7421242.html
Copyright © 2020-2023  润新知