[CERC2017]Intrinsic Interval

https://www.luogu.org/blog/ywycasm/solution-p4747#

这种“好的区间”,见得还是比较多的了。

mx-mi=r-l

比较经典的题是统计这样的区间个数。可以分治+大力分类讨论mx,mi的位置

但是这个题是一个询问。

先观察一些显而易见的性质:

1.好的区间的交也是好的区间

2.好的区间的并也是好的区间

所以,考虑对于一个询问,如果往后固定r找到了一个[L,R]的L左边最靠后的l,使得[l,r]是好区间,那么这就是最优答案了。后面再有也一定是包含关系。

固定r的话,不如试试离线扫描线?

用set存询问,L大到小排序。不合法直接break,因为更小的区间更不可能有左端点。合法更新答案,然后erase

问题在于,当r变成r+1的时候,我们怎样快速维护每个li的位置是不是有[li,r+1]是一个好的区间

一个比较棒的转化是:

如果[l,r]是一个好的区间,那么把这个区间的数排序之后,得到的序列相邻两项相差一定是1

定义(i,j)为一个好的二元组,当且仅当a[i]-a[j]=1

这样的两项的二元组在[l,r]中恰好有r-l个

所以,一个区间是好的区间,当且仅当好的二元组有r-l个。

线段树每个位置维护到r的二元组个数val

val+l=r则l位置是好的区间

l不变,不妨线段树位置初值为下标。

更新的话,设p[i]为权值为i的数的数组下标

多了一个a[r],对于左端点位于[1,p[a[r]-1]]和[1,p[a[r]+1]]的到r都会多一个二元组!

所以这些位置区间+1

存在val+l=r的找最右边的l?

发现tmp=val+l,最大就是r!(因为val最多就是r-l)

所以区间最大值最右边的那一个位置。

线段树随便搞

#include<bits/stdc++.h>
#define reg register int
#define mid ((l+r)>>1)
#define ls (x<<1)
#define rs (x<<1|1)
#define il inline
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=+;
int n,m;
int a[N],p[N];
struct po{
int mx,id;
po(){}
po(int vv,int dd){
mx=vv,id=dd;
}
bool friend operator <(po a,po b){
if(a.mx!=b.mx) return a.mx<b.mx;
return a.id<b.id;
}
}pr;
struct node{
po v;
int ad;
}t[*N];
void pushup(int x){
t[x].v=max(t[ls].v,t[rs].v);
}
void pushdown(int x){
if(!t[x].ad) return;
t[ls].v.mx+=t[x].ad;
t[ls].ad+=t[x].ad;
t[rs].v.mx+=t[x].ad;
t[rs].ad+=t[x].ad;
t[x].ad=;
}
void build(int x,int l,int r){
if(l==r){
t[x].v=po(l,l);
t[x].ad=;
return;
}
build(ls,l,mid);
build(rs,mid+,r);
pushup(x);
}
void add(int x,int l,int r,int L,int R,int c){
if(L<=l&&r<=R){
t[x].ad+=c;
t[x].v.mx+=c;
return;
}
pushdown(x);
if(L<=mid) add(ls,l,mid,L,R,c);
if(mid<R) add(rs,mid+,r,L,R,c);
pushup(x);
}
po query(int x,int l,int r,int L,int R){//ask the rightest mx's pos
if(L<=l&&r<=R) return t[x].v;
pushdown(x);
po ret;ret.mx=-,ret.id=-;
if(L<=mid) ret=max(ret,query(x<<,l,mid,L,R));
if(mid<R) ret=max(ret,query(x<<|,mid+,r,L,R));
return ret;
}
struct que{
int l,r,id;
bool friend operator <(que a,que b){
if(a.l!=b.l) return a.l>b.l;
if(a.r!=b.r) return a.r>b.r;
return a.id<b.id;
}
}q[N];
bool cmp(que a,que b){
return a.r<b.r;
} pair<int,int>ans[N];
set<que>s;
set<que>::iterator it;
int main(){
rd(n);
for(reg i=;i<=n;++i) rd(a[i]),p[a[i]]=i;
rd(m);
for(reg i=;i<=m;++i){
rd(q[i].l);rd(q[i].r);
q[i].id=i;
}
sort(q+,q+m+,cmp);
build(,,n);
int ptr=;
for(reg i=;i<=n;++i){
while(ptr<=m&&q[ptr].r==i){
s.insert(q[ptr]);++ptr;
}
if(a[i]>&&p[a[i]-]<i) add(,,n,,p[a[i]-],);
if(a[i]<n&&p[a[i]+]<i) add(,,n,,p[a[i]+],);
while(s.size()){
que now=*s.begin();
pr=query(,,n,,now.l);
if(pr.mx!=i){
break;
}
ans[now.id].first=pr.id;
ans[now.id].second=i; s.erase(now);
}
}
for(reg i=;i<=m;++i){
printf("%d %d\n",ans[i].first,ans[i].second);
}
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2018/12/25 19:27:07
*/

(mx-mi=r-l l+mx-mi=r,这个是不可以维护的,因为第一不好维护,第二没有最大值就是r的限制,不能查找)

总结:

离线+扫描线是处理区间询问的利器

尤其这个题,r对l的贡献又相对独立,而且可以支持快速单点增量改变,所以扫描线处理起来就游刃有余。

好区间的交、二元组的性质也是重要的思维过程。

upda:2019.3.17:主要还是利用二元组的转化思想,使得贡献独立

[CERC2017]Intrinsic Interval——扫描线+转化思想+线段树的更多相关文章

  1. BNU 28887——A Simple Tree Problem——————【将多子树转化成线段树+区间更新】

    A Simple Tree Problem Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on ZJU. O ...

  2. [CERC2017]Intrinsic Interval(神仙+线段树)

    题目大意:给一个1-n的排列,有一堆询问区间,定义一个好的区间为它的值域区间长度等于它的区间长度,求包这个询问区间的最小好的区间. 题解 做法太神了,根本想不到. %%%i207m. 结论:当一个区间 ...

  3. [CERC2017]Intrinsic Interval[scc+线段树优化建图]

    题意 给定一个长度为 \(n\) 的排列,有 \(q\) 次询问,每次询问一个区间 \([l,r]\) ,找到最小的包含 \([l,r]\) 的区间,满足这个区间包含了一段连续的数字. \(n\leq ...

  4. 洛谷 P4747 [CERC2017]Intrinsic Interval 线段树维护连续区间

    题目描述 题目传送门 分析 考虑对于 \([l,r]\),如何求出包住它的长度最短的好区间 做法就是用一个指针从 \(r\) 向右扫,每次查询以当前指针为右端点的最短的能包住 \([l,r]\) 的好 ...

  5. 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题

    “队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄>     线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...

  6. BZOJ4561:圆的异或并(扫描线+set||splay||线段树)

    在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面    积并.异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个圆内则不考虑. I ...

  7. 【HDU4630 No Pain No Game】 dp思想+线段树的离线操作

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4630 题意:给你n个数据范围在[1,n]中的数,m个操作,每个操作一个询问[L,R],让你求区间[L, ...

  8. HDU2795 billboard【转化为线段树。】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 hhanger大神的题目,水题都得有点思维. 题意:h*w的木板,放进一些1*L的物品,求每次放 ...

  9. [CERC2017] Intrinsic Interval

    首先理清这奇葩题意表述 给出一个\(1\)到\(n\)的排列\(p[]\)和\(m\)次询问,每次询问覆盖区间\([l,r]\)的最小区间\([a,b]\),满足\([a,b]\)内的元素排序后是连续 ...

随机推荐

  1. Laravel5.x 封装的上传图片类

    图片缩放需要用conposer安装 ImageManagerStatic类 可参考下面的地址安装: https://www.jb51.net/article/128159.htm 控制器里: 控制器里 ...

  2. 神级编辑器 sublime text 和 神级插件 emmet

    h1{foo}和a[href=#] 生成如下代码 <h1>foo</h1>  <a href="#"></a> 嵌套的使用 > ...

  3. 网站标题被篡改成北京赛车、PK10的解决处理办法

    客户网站于近日被跳转到赌博网站,打开后直接跳转到什么北京赛车,PK10等内容的网站上去,客户网站本身做了百度的推广,导致所有访问用户都跳转到赌博网站上去,给客户带来很大的经济损失,再一个官方网站的形象 ...

  4. 解决软件启动报error while loading shared libraries: libgd.so.2: cannot open shared object错误

    解决软件启动报error while loading shared libraries: libgd.so.2: cannot open shared object错误 今天安装启动nginx的时候报 ...

  5. nodejs环境变量配置

    步骤 创建文件夹:安装包 配置环境变量: export NODE_HOME=/root/安装包/node-v7.6.0-linux-x64 export PATH=$NODE_HOME/bin:$PA ...

  6. [转载]三小时学会Kubernetes:容器编排详细指南

    原翻译by梁晓勇 原英文:Learn Kubernetes in Under 3 Hours: A Detailed Guide to Orchestrating Containers 我很奇怪,为什 ...

  7. 基于Ubuntu Server 16.04 LTS版本安装和部署Django之(五):测试项目

    基于Ubuntu Server 16.04 LTS版本安装和部署Django之(一):安装Python3-pip和Django 基于Ubuntu Server 16.04 LTS版本安装和部署Djan ...

  8. 线上环境HBASE-1.2.0出现oldWALs无法自动回收情况;

    正常情况下,hmaster会定期清理oldWALs文件夹,一般该文件大小也就几百兆,但是我们线上 环境出现了该文件没有自动回收情况,如图: 该目录占用hdfs空间多达7.6T,浪费空间: 后来经过多番 ...

  9. Linq工具篇(1)——使用LinqPad

    学习Linq,有一个非常强大的工具,那就是LinqPad,具体功能有多强大就不说了,网上百度一下就可以知道,百闻不如一见,用用就知道,在网上下载一个绿色版的,无需安装,直接运行,界面如下: 具体功能, ...

  10. [转] 前端开发利器--Brackets 的七种武器和旁门左道

    转自:http://www.jianshu.com/p/ff7798aa4548 Brackets是Adobe开发的web编辑器,是一款免费开源.多平台支持的软件,并在于GitHub上维护.Brack ...