题意:

给定长度为 \(N\) 的序列 \(a\),求满足以下条件的 \((l,r)\) 对数:

  • \(1\le l\le r\le N\);

  • \(a_l,a_{l+1},\cdots,a_{r-1},a_r\) 是 \(1\sim r-l+1\) 的排列。

  • \(1\le N\le 10^6\);\(1\le a_i\le N\)。

思路

  • 首先,“排列”本身这个性质是很强的。因为排列本身需要从1开始,因此排列的数目必定不会很多。

    同时,只要我们知道了排列中最大的数,我们就知道了这个排列的长度。

  • 因此考虑去找区间中最大的数,然后去枚举区间的范围。在这个区间中,我们其实就将问题转化为了区间内的数的种类。只不过这里种类必须为区间长度。

    这种问题有一个很经典的转化,即维护一个数上一个与其值相同的数出现的位置,然后线段树去统计。

    不过这道题并不需要,因为我们只需要判断种类数是不是 \(n\) 就行了,因此可以用st表 \(O(1)\) 判断,只需要区间内所有数上一次出现的位置都小于区间左端点就行了。

  • 处理完最大值后就可以继续向两边递归去找。

复杂度

  • 这里的时间复杂度与启发式合并比较类似,平摊下来总体是 \(O(nlogn)\) 的。

code

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7;
int n,a[N],g[N][20],lst[N],lg[20];long long ans=0;
struct node
{
int val,loc;
}f[N][20];
node maxx(node x,node y){return x.val>=y.val?x:y;}
void init()
{
lg[0]=-1;for(int i=1;i<=n;i++) lg[i]=lg[i/2]+1;
for(int i=1;(1<<i)<=n;i++)for(int j=1;j+(1<<i)-1<=n;j++)
f[j][i]=maxx(f[j][i-1],f[j+(1<<(i-1))][i-1]),g[j][i]=max(g[j][i-1],g[j+(1<<(i-1))][i-1]);
}
node fmax(int l,int r){int x=lg[r-l+1];return maxx(f[l][x],f[r-(1<<x)+1][x]);}
int gmax(int l,int r){int x=lg[r-l+1];return max (g[l][x],g[r-(1<<x)+1][x]);}
bool query(int l,int r){return gmax(l,r)<l;}
void solve(int l,int r)
{
if(r<l) return;if(l==r) {ans+=(a[l]==1);return;}
node mval=fmax(l,r);
if(mval.loc-l<=r-mval.loc)
for(int i=max(l,mval.loc-mval.val+1),j=i+mval.val-1;i<=mval.loc&&j<=min(r,mval.loc+mval.val-1);++i,++j) ans+=query(i,j);
else for(int j=mval.loc,i=j-mval.val+1;i<=mval.loc,j<=min(r,mval.loc+mval.val-1);++i,++j) if(i<l) continue;else ans+=query(i,j);
solve(l,mval.loc-1),solve(mval.loc+1,r);
}
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n;for(int i=1;i<=n;i++) {cin>>a[i];f[i][0]={a[i],i},g[i][0]=lst[a[i]],lst[a[i]]=i;}
init();solve(1,n);cout<<ans<<'\n';
return 0;
}

P10833 [COTS 2023] 下 Niz题解的更多相关文章

  1. poj2391 Ombrophobic Bovines 题解

    http://poj.org/problem?id=2391 floyd+网络流+二分 题意:有一个有向图,里面每个点有ai头牛,快下雨了牛要躲进雨棚里,每个点有bi个雨棚,每个雨棚只能躲1头牛.牛可 ...

  2. ZOJ1081:Points Within——题解

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1081 题目大意:给定一个点数为 n 的多边形,点按照顺序给出,再给出 m ...

  3. Codeforces Round 596 题解

    万幸的是终于碰上了一场上分好场. 不幸的是一开始差点不会 A. 万幸的是想了个不那么稳的结论过了 pretest. 不幸的是罚时很高,而且慌得一比. 万幸的是然后半个小时内把 B 和 C 码了. 不幸 ...

  4. Codeforces525E Anya and Cubes(双向搜索)

    题目 Source http://codeforces.com/contest/525/problem/E Description Anya loves to fold and stick. Toda ...

  5. CF448C Painting Fence (分治递归)

    Codeforces Round #256 (Div. 2) C C. Painting Fence time limit per test 1 second memory limit per tes ...

  6. POJ 2385 Apple Catching

    比起之前一直在刷的背包题,这道题可以算是最纯粹的dp了,写下简单题解. 题意是说cows在1树和2树下来回移动取苹果,有移动次数限制,问最后能拿到的最多苹果数,含有最优子结构性质,大致的状态转移也不难 ...

  7. 【BZOJ】【1018】【SHOI2008】堵塞的交通traffic

    线段树 这题的线段树+分类讨论蛮神奇的……我以前学的线段树简直就是渣渣QAQ 看了下ydc题解里的思想>_>用线段树维护连通性!那么就自己写吧……每个节点表示一段区间的连通性(我的叶子节点 ...

  8. TJOI2015 day2解题报告

    TJOI2015终于写完啦~~~ T1:[TJOI2015]旅游 描述:(BZ没题面只能口述了..)一个人在一棵树上走,每次从a->b会进行一次贸易(也就是在这条路径上买入物品然后在后面卖出)然 ...

  9. 线性规划与网络流24题●09方格取数问题&13星际转移问题

    ●(做codevs1908时,发现测试数据也涵盖了1907,想要一并做了,但因为“技术”不佳,搞了一上午) ●09方格取数问题(codevs1907  方格取数3) 想了半天,也没成功建好图: 无奈下 ...

  10. Codeforces Round #401 (Div. 2)

    和FallDream dalao一起从学长那借了个小号打Div2,他切ABE我做CD,我这里就写下CD题解,剩下的戳这里 AC:All Rank:33 小号Rating:1539+217->17 ...

随机推荐

  1. 聊聊 FocusSearch/focus_mcp_sql:Text2SQL 的新玩法

    最近在 GitHub 上逛的时候,发现了一个挺有意思的项目--FocusSearch/focus_mcp_sql.作为一个对 Text2SQL 有点小研究的前端码农,我忍不住想和大家聊聊这个工具.它不 ...

  2. [NOI2014] 购票 题解

    首先发现 \(p_x\times dis(x,y)+q_x\) 异常像是能斜率优化的样子,那先把求 \(f_x\) 的式子写出来(下设 \(d_x\) 表示 \(x\) 到根的距离): \[f_x=\ ...

  3. [HDU5396] Expression 题解

    每次合并两个数,做过石子合并的人都能看出来是区间 dp. 设状态 \(dp_{i,j}\) 表示区间 \([i,j]\) 中合并为一个数的所有情况之和. 那么我们就可以枚举断点 \(k\): \(b_ ...

  4. 发那科机器人R2000iC齿轮箱维修方法步骤归纳

    一.发那科机器人R2000iC齿轮箱常见故障类型及原因 齿轮磨损:长时间的重载工作或润滑不良可能导致齿轮磨损,表现为噪音增大.振动加剧等. 轴承故障:轴承承受了齿轮箱的径向和轴向载荷,其故障可能导致齿 ...

  5. 小米9刷twrp Rec 以及写入Magisk详细教程

    首先手机必须先解锁BL锁才能继续: ---------------------- 小米官方BL解锁教程:点此看教程 ---------------------- 解完锁后开始操作: 工具包:点此下载 ...

  6. C#方法练习

    提示用户输入用户名和密码,写一个方法来判断用户输入的是否正确,返回给用户一个登陆结果,并且还要单独的返回给用户一个登陆信息 ,如果用户名错误,除了返回登陆结果之外,还要返回一个 "用户名错误 ...

  7. 朝花夕拾,帮三年前的自己改bug

    三年前,滨海之边马上毕业的老少年 经过几天半死不活的思考之后决定干前端 那个时候为了面试各种css属性js API背的是滚瓜烂熟 然后投简历,企业要项目经验, 我没有工作我哪来的项目经验啊 没人会管你 ...

  8. 当你在浏览器中输入 google.com 后按下回车发生了什么?

    按下"g"键 接下来的内容介绍了物理键盘和系统中断的工作原理,但是有一部分内容却没有涉及.当你按下"g"键,浏览器接收到这个消息之后,会触发自动完成机制.浏览器 ...

  9. oracle怎么查询重复的数据

    在oracle中,可以利用count()函数配合select查询语句来查询重复的数据,语法为"select userCode from user group by userCode havi ...

  10. linux重启后,启动docker和docker对应的服务

    我的项目部署在docker上,linux关闭之后,项目要重启,在此做一个记录1.启动linux之后,执行docker images或者docker ps,如果出现下面的错误Cannot connect ...