ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[题解] [CERC2017]Intrinsic Interval

2021-09-30 07:31:22  阅读:204  来源: 互联网

标签:Interval rs int 题解 mn tag 端点 区间 Intrinsic


[题解] [CERC2017]Intrinsic Interval

点此看题

如果你做过类似的一类模型题,你确实会认为这道思维题,其实就是一道套路题。

建模

见到此类给你一些区间,求解合法区间个数或者是什么的问题,可以往这里想。

  1. 把询问区间按照右端点排序。

  2. 从左到右依次枚举右端点,用数据结构来维护左端点。

当然,最重要的是第二步,第一步是离线思想,第二步是统计思想

通常,在并非特别复杂的情况下,第二步的数据结构采用线段树即可,但具体的不是用什么,而是怎么维护。

那么就需要发现题目性质:本征区间为极差减去区间长度等于 \(-1\) 的且包含询问区间的一个区间,或者说,满足 \(max-min=r-l\),注意 \(r-l\) 并不是区间长度。

发现这个关键性质,就可以考虑线段树维护这个东西了。

\[max-min-(r-l)\geq0 \]

当取等时,这就是一个合法的左端点,因此可以维护这个东西的最小值来判断。

这个模型关键的是第三步:

  1. 考虑加入当前右端点对已有的左端点的影响。

通俗的讲,加入当前右端点 \(r\) 后,之前所有的 \([l,r-1]\) 的区间都会扩展一个单位,这需要我们在线段树上更新左端点的信息,也就是更新 \(max,min,(r-l)\) 这三个信息。

\(r-l\) 不用说,肯定是 \(+1\),那么整个维护的值 \(-1\)。

对于 \(max,min\) 的维护,设 \(l_1,l_2\) 依次为 \(r\) 从右往左数第一个比 \(a_r\) 大和比 \(a_r\) 小的位置,对于这类问题,可以用单调栈维护(比较常见)。

那么处于 \([l_1+1,r]\) 的这部分左端点,它们到右端点 \(r\) 的最大值都会取到 \(a_r\),可以在维护单调栈的时候进行撤销,然后再把 \(a_r\) 的值更新进去。

具体来说,对于单调栈(不妨设单调递减)中相邻的两个点 \(u,v\),\([u+1,v-1]\) 这一段的值均 \(\leq a_v\) .

在维护单调栈单调性的同时,顺便维护一下撤销的东西即可。

最后就是查询,有一个结论是:

如果当前的 \(r\) 对应于一个合法的最大的 \(l\),那么这个 \([l,r]\) 就是最小的区间。

证明自己反证法证一下。

而这个题也可以有一个变式:

如果不是排列了怎么办?

借用 HH的项链 的思想,区间数颜色的关键在于在最后一次出现的位置统计答案,因此记录 \(last\) 更换一下 \(r-l\) 的维护即可。

Continuous Intervals,可以说是加强版,需要区间数颜色并且维护合法区间的个数。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
template <typename T>
inline T read(){
	T x=0;char ch=getchar();bool fl=false;
	while(!isdigit(ch)){if(ch=='-')fl=true;ch=getchar();}
	while(isdigit(ch)){
		x=(x<<3)+(x<<1)+(ch^48);ch=getchar();
	}
	return fl?-x:x;
}
#include <vector>
#include <set>
const int maxn = 1e5 + 10;
#define Pair pair<int,int>
#define mp make_pair
namespace Tree{
struct tree{
	int l,r;
	int mn,tag;
}t[maxn<<2];
#define ls (p<<1)
#define rs (p<<1|1)
#define mid ((l+r)>>1)
inline void pushup(int p){
	t[p].mn=min(t[ls].mn,t[rs].mn);
}
inline void pushdown(int p){
	if(!t[p].tag)return ;
	t[ls].mn+=t[p].tag;t[rs].mn+=t[p].tag;
	t[ls].tag+=t[p].tag;t[rs].tag+=t[p].tag;
	t[p].tag=0;
}
void build(int p,int l,int r){
	t[p].l=l;t[p].r=r;
	if(l==r)return t[p].mn=l,void();
	build(ls,l,mid);build(rs,mid+1,r);
	pushup(p);
}
void update(int p,int x,int y,int val){
	int l=t[p].l,r=t[p].r;
	if(x>y)return ;
	if(x<=l && r<=y){
		t[p].mn+=val;t[p].tag+=val;return ;
	}
	pushdown(p);
	if(x<=mid)update(ls,x,y,val);
	if(y>mid)update(rs,x,y,val);
	pushup(p);
}
int query(int p,int x,int y){
	int l=t[p].l,r=t[p].r;
	if(t[p].mn>0)return -1;
	if(l==r)return l;
	pushdown(p);
	if(y>mid && !t[rs].mn){
		int res=query(rs,x,y);
		if(res!=-1)return res;
	}
	if(x<=mid && !t[ls].mn)return query(ls,x,y);
	return -1;
}
}using namespace Tree;
int n,m,a[maxn];
int stk1[maxn],stk2[maxn],top1,top2;
vector<Pair> pos[maxn];
multiset<Pair> s;
Pair ans[maxn];
#define read() read<int>()
int main(){
	n=read();
	for(int i=1;i<=n;i++)a[i]=read();
	m=read();
	for(int i=1;i<=m;i++){
		int l=read(),r=read();
		pos[r].emplace_back(l,i);
	}
	build(1,1,n);
	for(int i=1;i<=n;i++){
		int x,y;
		while(top1 && a[stk1[top1]]<a[i]){
			y=stk1[top1];top1--;
			x=stk1[top1]+1;
			update(1,x,y,-a[y]);
		}
		x=stk1[top1]+1;y=i;
		update(1,x,y,a[y]);
		stk1[++top1]=i;
		while(top2 && a[stk2[top2]]>a[i]){
			y=stk2[top2];top2--;
			x=stk2[top2]+1;
			update(1,x,y,a[y]);
		}
		x=stk2[top2]+1;y=i;
		update(1,x,y,-a[y]);
		stk2[++top2]=i;
		update(1,1,n,-1);
		for(auto x:pos[i])s.insert(x);
		while(s.size()){
			auto it=s.end();it--;
			int l=it->first,res=query(1,1,l);
			if(res==-1)break;
			s.erase(it);
			ans[it->second].first=res;
			ans[it->second].second=i;
		}
	}
	for(int i=1;i<=m;i++)printf("%d %d\n",ans[i].first,ans[i].second);
	return 0;
}

标签:Interval,rs,int,题解,mn,tag,端点,区间,Intrinsic
来源: https://www.cnblogs.com/Liang-sheng/p/15355137.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有