这题正解应该是扫描线,就是发现DP的区间在两个维度都为连续段,于是可以直接扫描线。但不幸的是,扫描线常数过大,无法通过本题。

考虑分治。对于分治区间[l,r],可以记录pre和nxt表示其前/后一次出现的位置,每当遇到一个出现次数=1的数,可以直接把区间分为两半判断,反之则丢掉这个数,而仅会分治一次,且掐断地方是先判两边,复杂度近似O(nlogn)。

实在太坑了,其实是一道练习扫描线的好题qwq

#include<cstdio>
#include<algorithm>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
const int N=2e5+;
typedef long long ll;
struct line{int x,l,r,v;}c[N<<];
int n,m,a[N],b[N],L[N],R[N],pre[N],sum[N<<],cnt[N<<];
bool cmp(line a,line b){return a.x<b.x;}
void insert(int a1,int a2,int b1,int b2)
{c[++m]=(line){a1,b1,b2,},c[++m]=(line){a2+,b1,b2,-};}
void build(int l,int r,int rt)
{
sum[rt]=cnt[rt]=;
if(l==r)return;
int mid=l+r>>;
build(lson),build(rson);
}
void pushup(int l,int r,int rt)
{
if(cnt[rt])sum[rt]=r-l+;
else if(l==r)sum[rt]=;
else sum[rt]=sum[rt<<]+sum[rt<<|];
}
void update(int L,int R,int v,int l,int r,int rt)
{
if(L<=l&&r<=R){cnt[rt]+=v,pushup(l,r,rt);return;}
int mid=l+r>>;
if(L<=mid)update(L,R,v,lson);
if(R>mid)update(L,R,v,rson);
pushup(l,r,rt);
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
build(,n,);
for(int i=;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
sort(b+,b+n+);
m=unique(b+,b+n+)-b-;
for(int i=;i<=n;i++)a[i]=lower_bound(b+,b+m+,a[i])-b;
m=;
for(int i=;i<=n;i++)pre[i]=;
for(int i=;i<=n;i++)L[i]=pre[a[i]],pre[a[i]]=i;
for(int i=;i<=n;i++)pre[i]=n+;
for(int i=n;i;i--)R[i]=pre[a[i]],pre[a[i]]=i;
for(int i=;i<=n;i++)insert(L[i]+,i,i,R[i]-);
sort(c+,c+m+,cmp);
ll ans=;
for(int i=,p=;i<=n;i++)
{
while(p<m&&c[p+].x==i)p++,update(c[p].l,c[p].r,c[p].v,,n,);
ans+=sum[];
}
if(ans==1ll*n*(n+)/)puts("non-boring");
else puts("boring");
}
}

扫描线的TLE代码

#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
const int N=2e5+;
int n,m,a[N],pre[N],nxt[N];
map<int,int>lst;
bool solve(int l,int r)
{
if(l>=r)return ;
int p=l,q=r;
while(p<=q)
{
if(pre[p]<l&&nxt[p]>r)return solve(l,p-)&&solve(p+,r);p++;
if(pre[q]<l&&nxt[q]>r)return solve(l,q-)&&solve(q+,r);q--;
}
return ;
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
lst.clear();
scanf("%d",&n);
for(int i=,pos;i<=n;i++)scanf("%d",&a[i]),pos=lst[a[i]],nxt[pos]=i,pre[i]=pos,lst[a[i]]=i;
for(int i=;i<=n;i++)nxt[lst[a[i]]]=n+;
if(solve(,n))puts("non-boring");else puts("boring");
}
}

分治的AC代码

BZOJ4059[Cerc2012]Non-boring sequences(扫描线/分治)的更多相关文章

  1. bzoj4059 [Cerc2012]Non-boring sequences && bzoj5200 [NWERC2017]Factor-Free Tree

    https://konnyakuxzy.github.io/BZPRO/JudgeOnline/4059.html https://cn.vjudge.net/problem/Gym-100624D ...

  2. 【启发式拆分】bzoj4059: [Cerc2012]Non-boring sequences

    这个做法名字是从武爷爷那里看到的…… Description 我们害怕把这道题题面搞得太无聊了,所以我们决定让这题超短.一个序列被称为是不无聊的,仅当它的每个连续子序列存在一个独一无二的数字,即每个子 ...

  3. bzoj4059 [Cerc2012]Non-boring sequences

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4059 [题解] 考虑分治.定义过程solve(l,r)为判断全在[l,r]范围内的所有连续子 ...

  4. BZOJ 4059: [Cerc2012]Non-boring sequences(启发式分治)

    传送门 解题思路 首先可以想到要预处理一个\(nxt_i\)和\(pre_i\),表示前后与当前位置权值相同的节点,那么这样可以迅速算出某个点在某段区间是否出现多次.然后这样的话就考虑分治,对于\([ ...

  5. UVA1608-Non-boring sequences(分治)

    Problem UVA1608-Non-boring sequences Accept: 227  Submit: 2541Time Limit: 3000 mSec Problem Descript ...

  6. Non-boring sequences(启发式分治)

    题意:一个序列被称作是不无聊的,当且仅当,任意一个连续子区间,存在一个数字只出现了一次,问给定序列是否是不无聊的. 思路:每次找到一个只出现了一次的点,其位置的pos,那么继续分治[L,pos-1], ...

  7. UVA - 1608 Non-boring sequences (分治)

    题意:如果一个序列的任意连续子序列中至少有一个只出现一次的元素,则称这个序列式为non-boring.输入一个n(n≤200000)个元素的序列A(各个元素均为109以内的非负整数),判断它是否无聊. ...

  8. HDU 5324 Boring Class CDQ分治

    题目传送门 题目要求一个3维偏序点的最长子序列,并且字典序最小. 题解: 这种题目出现的次数特别多了.如果不需要保证字典序的话直接cdq就好了. 这里需要维护字典序的话,我们从后往前配对就好了,因为越 ...

  9. 【刷题】BZOJ 4059 [Cerc2012]Non-boring sequences

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

随机推荐

  1. spring boot配置druid连接池连接mysql

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  2. MongoDB七-运维技术

    复制来自:http://www.cnblogs.com/huangxincheng/archive/2012/03/08/2384571.html 这一篇我们以管理员的视角来看mongodb,作为一名 ...

  3. 解决CGrIdCtrl合并单元格后继续拆分后的问题

    DWORD dwMergeCellCount = vMergeCells.size(); ; i < dwMergeCellCount; i++){ m_HFlexGrid.SplitCells ...

  4. Kubernetes1-K8s的简单介绍(转载)

    一.简介 1.什么是Kubernetes 简称K8s,用8代替8个字符"ubernerte"而成的速写,K8s是一个开源的容器编排平台,它是一个跨主机集群的开源容器调度平台,用于管 ...

  5. BZOJ:2242: [SDOI2011]计算器

    题解:BSGS 问题:map空间 BSGS判无解 a%p!=0 0与最小非负整数 有区别 函数传参类型转换int->long long long long ->int; 费马小定理充分必要 ...

  6. jQuery课上笔记19.5.17

    jQuery 选择器 $("*"):所有元素 $("#idname"):id="idname"的元素 $(".classname& ...

  7. cf1208 D Restore Permutation (二分+树状数组)

    题意 让你构造一个长度为n的序列,记为p1……pn,(这个序列是1~n的全排列的一种) 给你n个数,记为s1……sn,si的值为p1……pi-1中小于pi的数的和. 思路 显然,应该倒着来,也就是从p ...

  8. xv6的启动过程

    bootloader 1. bootasm.S : start32 2. bootmain.c : bootmain kernel 3. main.c : main 4. proc.c : useri ...

  9. JS-表单非空验证

    JavaScript 表单验证 JavaScript 可用来在数据被送往服务器前对 HTML 表单中的这些输入数据进行验证. 实例:1.用户名的非空验证代码如下: <head> <m ...

  10. OpenCV2基础操作----直线、矩形、圆、椭圆函数的使用

    opencv2几个画图函数的调用 要用到几个随机变量: int fr = rand()%frame.rows; int fc = rand()%frame.cols; int b = rand()%2 ...