这题正解应该是扫描线,就是发现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代码

最新文章

  1. .NET跨平台之旅:ASP.NET Core从传统ASP.NET的Cookie中读取用户登录信息
  2. jQuery学习笔记(控件位置定位、尺寸大小的获取等)
  3. 【原】iOS学习之KVC原理
  4. hbase 使用
  5. Struts2.3+Spring+iBatis 初学之问题判断
  6. 转:db2 iptables相关用法(1)
  7. Java的外部类和内部类+静态变量和非静态变量的组合关系
  8. 想了解JAVA的,看看(转载)
  9. 最受 Web 开发者欢迎的 NoSQL 和关系数据库
  10. [LeetCode#156] Binary Tree Upside Down
  11. JavaScript function函数种类(转)
  12. sparse autoencoder
  13. Java中的事件监听机制
  14. Vocabulary & Phrase
  15. 一个任务:(小甲鱼python视频第29讲) 代码整理与总结
  16. php优秀框架codeigniter学习系列——CI_Output类的学习
  17. 机器学习进阶-图像梯度计算-scharr算子与laplacian算子(拉普拉斯) 1.cv2.Scharr(使用scharr算子进行计算) 2.cv2.laplician(使用拉普拉斯算子进行计算)
  18. Spring中 &lt;context:property-placeholder 的使用与解析 .properties 配置文件的加载
  19. Django的model中创建表
  20. BZOJ 1497 [NOI2006]最大获利

热门文章

  1. ACM-可乐兑换
  2. linux下如果指令太长,怎么换行输入;怎么快速删除整行命令;怎么快速移动到命令最前或者最后
  3. JavaScript的运算符、条件判断、循环、类型转换(9.25 第十一天)
  4. POJ - 2253 Frogger(最短路Dijkstra or flod)
  5. CSS实现背景图片透明和文字不透明效果
  6. 十四、CI框架之数据库以参数形式插入操作
  7. 十、CI框架之通过参数的办法输出URI路径
  8. Java并发基础类AbstractQueuedSynchronizer的实现原理简介
  9. 题解P4201: [NOI2008]设计路线
  10. JetBrains系列-插件