CF1156E Special Segments of Permutation题解瞎搞 单调栈
Posted chriskkk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1156E Special Segments of Permutation题解瞎搞 单调栈相关的知识,希望对你有一定的参考价值。
题面:http://codeforces.com/contest/1156/problem/E
Luogu翻译:https://www.luogu.com.cn/problem/CF1156E
话说Luogu要改域名了。
大意:给定一个长度为n的排列p,求有多少区间[l,r]满足,p[l]+p[r]=maxp[i],其中l<=i<=r
据说可以笛卡尔树。
可是我不会。
那么就瞎搞。
预处理出左边第一个比a[i]大的数的位置,记为L[i]
R[i]同理为右边。
这个可以用单调栈求。
然后就可以枚举l和r了。
但是显然这样会爆炸。
但是由于题目的限制,可以只枚举一边。
另外一边直接查询有没有。
比如枚举了l,那么p[r]=pmax-p[l]
只用知道右边有没有p[r]就可以了。
代码如下:
#include<bits/stdc++.h> using namespace std; const int maxn=2*1e5+10; int n,a[maxn],pos[maxn]; long long ans; int L[maxn],R[maxn],s[maxn]; int main() scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); pos[a[i]]=i; int top=0; for(int i=1;i<=n;i++) while(top && a[s[top]]<a[i]) top--; L[i]=s[top]; s[++top]=i; top=0;s[top]=n+1; for(int i=n;i;i--) while(top && a[s[top]]<a[i]) top--; R[i]=s[top]; s[++top]=i; for(int i=1;i<=n;i++) if(i-L[i]<R[i]-i) for(int j=L[i]+1;j<i;j++) if(pos[a[i]-a[j]]>i && pos[a[i]-a[j]]<R[i]) ans++; else for(int j=i+1;j<R[i];j++) if(pos[a[i]-a[j]]<i && pos[a[i]-a[j]]>L[i]) ans++; printf("%d\n",ans); return 0;
以上是关于CF1156E Special Segments of Permutation题解瞎搞 单调栈的主要内容,如果未能解决你的问题,请参考以下文章
E. Special Segments of Permutation(双指针&分治)
Codeforces1156 E. Special Segments of Permutation(单调栈,复杂度分析)