又是一道神仙题。考试的时候居然打了一个回滚莫队,不知道我咋想的……

先说一个某OJT80,洛谷T5分的思路(差距有点大):

可以把位置和编号映射一下,区间内最大值和最小值对应的位置,每次更新,直到找到符合条件的情况,复杂度玄学。最值的维护可以用ST表或者线段树,前者复杂度低些。

然后说正解吧:

先放出来看不懂的作者的正解:

分治法,离线处理。假设现在处理的询问都包含在[L,R] 中,设mid=(L+R)/2。然后将包含在[L,mid],[mid+1,R] 的区间分治处理。剩下的就是包含[mid,mid+1] [mid,mid+1]的询问,然后找出包含[mid,mid+1] [mid,mid+1]的所有优美区间,用这些优美区间更新询问的答案。

时间复杂度O(n(logn)^2)。

上面的我不会。

然后正解1:scc+线段树优化建图

但是我不会……

正解2:

扫描线+转化思想+线段树,虽然我不会扫描线(我还以为这玩意只能用到二维呢)……

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

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

好的区间的判断条件:maxn-minn=r-l,但是这样并不够,如果只是这样判断的话,就回到了80分的思路,不断拓展区间判断。

另一个判断条件是l+num=r,num为区间中形如(a,a+1)这样的点对数(将区间排序后就很显然了)。

所以我们离线将询问排序扔到set里,固定r,然后用线段树维护左边的信息及对应的l,令叶子节点的初始值为l,查询只需要找线段树中满足条件最靠右的,而每次r右移,给1~b[a[r]+-1]的区间的点对数+1,当然要判断一下,必须在它左边。

其实我开始有一个问题,如果固定r,能保证区间的右端点一定是r吗?显然是不能的,但是在处理r时,如果没有满足条件的l,这个询问就会被剩到set中,在r+1后继续更新,就保证了正确性。

 #include<algorithm>
#include<iostream>
#include<cstdio>
#include<set>
#define LL long long
#define MAXN 1000010
using namespace std;
struct ques
{
int l,r,id;
friend bool operator < (ques a,ques b)
{return a.l==b.l?(a.r==b.r?a.id<b.id:a.r>b.r):a.l>b.l;}
}q[MAXN];
set<ques> s;
set<ques>::iterator it;
pair<int,int>ans[MAXN];
int n,m,a[MAXN],b[MAXN];
struct po
{
int mx,id;
friend bool operator < (po a,po b)
{return a.mx==b.mx?a.id<b.id:a.mx<b.mx;}
};
struct tree
{
po v;int ad,l,r;
#define l(x) tr[x].l
#define r(x) tr[x].r
#define ad(x) tr[x].ad
#define v(x) tr[x].v
#define ls(x) (x<<1)
#define rs(x) (ls(x)+1)
}tr[MAXN*];
void pushup(int x)
{
v(x)=max(v(ls(x)),v(rs(x)));
}
void down(int x)
{
if(!ad(x))return;
ad(ls(x))+=ad(x);
ad(rs(x))+=ad(x);
v(ls(x)).mx+=ad(x);
v(rs(x)).mx+=ad(x);
ad(x)=;
}
void build(int x,int l,int r)
{
l(x)=l,r(x)=r;
if(l==r)
{v(x).id=v(x).mx=l;ad(x)=;return;}
int mid=(l+r)>>;
build(ls(x),l,mid);
build(rs(x),mid+,r);
pushup(x);
}
void add(int x,int l,int r,int y)
{
if(l(x)>=l&&r(x)<=r)
{v(x).mx+=y;ad(x)+=y;return;}
down(x);
int mid=(l(x)+r(x))>>;
if(l<=mid)add(ls(x),l,r,y);
if(r>mid) add(rs(x),l,r,y);
pushup(x);
}
po ask(int x,int l,int r)
{
down(x);
if(l(x)>=l&&r(x)<=r)return v(x);
int mid=(l(x)+r(x))>>;po ans={-,-};
if(l<=mid)ans=max(ans,ask(ls(x),l,r));
if(r>mid) ans=max(ans,ask(rs(x),l,r));
return ans;
}
bool cmp(ques a,ques b)
{
return a.r<b.r;
}
inline int read();
signed main()
{
// freopen("in.txt","r",stdin); n=read();
for(int i=;i<=n;i++)a[i]=read(),b[a[i]]=i;
m=read();
for(int i=;i<=m;i++)q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+,q+m+,cmp);
build(,,n);
int ptr=;
for(int i=;i<=n;i++)
{
while(ptr<=m&&q[ptr].r==i)
s.insert(q[ptr]),ptr++;
if(a[i]>&&b[a[i]-]<i)add(,,b[a[i]-],);
if(a[i]<n&&b[a[i]+]<i)add(,,b[a[i]+],);
while(s.size())
{
ques now=*s.begin();
po tem=ask(,,now.l);
if(tem.mx!=i)break;
ans[now.id].first=tem.id;
ans[now.id].second=i;
s.erase(now);
}
}
for(int i=;i<=m;i++)
printf("%d %d\n",ans[i].first,ans[i].second);
}
inline int read()
{
int s=;char a=getchar();
while(a<''||a>'')a=getchar();
while(a>=''&&a<=''){s=s*+a-'',a=getchar();}
return s;
}

 声讨某ex_face一干人等卡分快调块长卡掉数据

[***]HZOJ 优美序列的更多相关文章

  1. 优美序列(sequence)

    问题描述 Lxy养了N头奶牛,他把N头奶牛用1..N编号,第i头奶牛编号为i.为了让奶牛多产奶,每天早上他都会让奶牛们排成一排做早操.奶牛们是随机排列的.在奶牛排列中,如果一段区间[L,R]中的数从小 ...

  2. 8.5 NOIP模拟测试13 矩阵游戏+跳房子+优美序列

    T1矩阵游戏 数学题.首先这一列这一行先乘还是后乘对最后答案没有影响.a[i][j]表示矩阵中原始的值,h[i]表示i行的累乘,l[i]表示i列的累乘.易得ans=Σa[i][j]*h[i]*l[i] ...

  3. [JZOJ6279] 2019.8.5【NOIP提高组A】优美序列

    题目 题目大意 给你一个排列以及若干区间,对于每个区间,问包含它的最小的优美序列的区间. 所谓优美序列,即将权值排序后能够得到连续的排列. 思考历程 优美序列显然满足这个条件:\(mx-mn=r-l\ ...

  4. NOIP模拟测试13「矩阵游戏&#183;跳房子&#183;优美序列」

    矩阵游戏 考试时思路一度和正解一样,考试到最后还是打了80分思路,结果80分打炸了只得了40分暴力分 题解 算出来第一列的总值,每次通过加每两列之间的差值得出下一列的总值 算第一列我们只需要让当前点* ...

  5. 【模拟8.05】优美序列(线段树 分块 ST算法)

    如此显然的线段树,我又瞎了眼了 事实上跟以前的奇袭很像....... 只要满足公式maxn-minn(权值)==r-l即可 所以可以考虑建两颗树,一棵节点维护位置,一棵权值, 每次从一棵树树上查询信息 ...

  6. [LeetCode] Beautiful Arrangement 优美排列

    Suppose you have N integers from 1 to N. We define a beautiful arrangement as an array that is const ...

  7. dir命令只显示文件名

    dir /b 就是ls -f的效果 1057 -- FILE MAPPING_web_archive.7z 2007 多校模拟 - Google Search_web_archive.7z 2083 ...

  8. 全国信息学奥林匹克联赛(NOIP2014)复赛 模拟题Day2 长乐一中

    题目名称 改造二叉树 数字对 交换 英文名称 binary pair swap 输入文件名 binary.in pair.in swap.in 输出文件名 binary.out pair.out sw ...

  9. NOIP模拟 13

    我终于又厚颜无耻地赖着没走 ...... T1 矩阵游戏 用了30hmin找规律,然后发现貌似具有交换律,然后发现貌似有通项公式,然后发现貌似每次操作对通项的影响是相同的,然后发现貌似跟N没啥关系.. ...

随机推荐

  1. win7开机启动项设置

    Windows系统自身就有启动项命令可以进行设置: 要说到修改启动项,当然首推Windows系统自带的“MSCONFIG”命令,XP等其他Windows系统用户使用方法是一模一样的. 1.点击“开始” ...

  2. Django-2.2.1学习感悟

    或许是看的教程比较老,跟不上2.2.1版本的Django,所以在编写代码时可以说是bug不断,这算是编程必经阶段 每当遇到django的bug logging,先看头几行再看最后几行,能自己解决最好, ...

  3. 实用Jupyter Notebook扩展工具——提升你的工作效率

    Jupyter Notebook 现已成为数据分析,机器学习的必备工具.因为它可以让数据分析师集中精力向用户解释整个分析过程.通过安装一些扩展工具,可以让你在Jupyter Notebook上的工作效 ...

  4. paip.前端载入时间分析之道优化最佳实践

    paip.前端载入时间分析之道优化最佳实践 1.另存为 ,查看文件尺寸..和图片. 2.view the 另存为的htm静态的文件单个的载入,看时间...能够排除编程语言的问题and 数据库.. ## ...

  5. 模拟3题解 T3建造游乐园

    T3建造游乐园 这题的关键是推式子 i个点中,有g[i]个方案是度为偶数但不一定连通那么就要减去不合法的设已有j个合法,其个数为f[j],剩下i-j个的方案数是g[i-j]选出来一个固定的点在合法的j ...

  6. LUOGU P1081 开车旅行 (noip 2012)

    传送门 解题思路 这道题刚了一下午,主要就刚在set那里了.先写了一个暴力70分..之后优化预处理,看着大佬神犇们都用的什么双向链表之类的东西,本蒟蒻不会,又懒得手写平衡树,就拿了个set搞了搞,感觉 ...

  7. 洛谷1081 (NOIp2012) 开车旅行——倍增预处理

    题目:https://www.luogu.org/problemnew/show/P1081 预处理从每个点开始a能走多少.b能走多少.可以像dp一样从后往前推. 但有X的限制.所以该数组可以变成倍增 ...

  8. cf round 480E The Number Games

    题意:给一棵树,点$i$的点权是$2^i$,你需要删掉$k$个点,使得剩下的点连通的情况下剩下的点权值和最大. $k \leq n \leq 10^6$ 如果考虑删哪些点,是不好考虑的,会出问题. 反 ...

  9. selenium(2):环境搭建完成后,初步运行遇到的问题

    检验是否搭建成功. . 问题一:运行时候,报错:请停用以开发者模式运行的扩展程序 出现错误如下: 原因:chromedriver的版本号过低了. 解决办法:应该安装与chrome版本对应的chrome ...

  10. Linux常用命令操作详解

    https://mp.weixin.qq.com/s/IR4yy7Q0mOA_XV16R21CdQ 一:Linux下tomcat服务的启动.关闭与错误跟踪 使用PuTTy远程连接到服务器以后,通常通过 ...