题目链接:Codeforces - Special Segments of Permutation
考虑分治最大值,然后启发式求答案。
ST表预处理出区间最大值的位置即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10;
int n,a[N],pos[N]; long long res;
int st[N][20],lg[N];
inline void build(){
lg[0]=-1;
for(int i=1;i<=n;i++) lg[i]=lg[i>>1]+1;
for(int i=1;i<=n;i++) st[i][0]=i;
for(int j=1;j<=17;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
st[i][j]=a[st[i][j-1]]>=a[st[i+(1<<(j-1))][j-1]]?st[i][j-1]:st[i+(1<<(j-1))][j-1];
}
inline int ask(int l,int r){
int t=lg[r-l+1];
return a[st[l][t]]>=a[st[r-(1<<t)+1][t]]?st[l][t]:st[r-(1<<t)+1][t];
}
void solve(int l,int r){
if(l>=r-1) return ;
int mid=ask(l,r),mx=a[mid];
if(mid-l<=r-mid){
for(int i=l;i<mid;i++) if(pos[mx-a[i]]>mid&&pos[mx-a[i]]<=r) res++;
}else{
for(int i=mid+1;i<=r;i++) if(pos[mx-a[i]]>=l&&pos[mx-a[i]]<mid) res++;
}
solve(l,mid-1),solve(mid+1,r);
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),pos[a[i]]=i; build();
solve(1,n);
cout<<res;
return 0;
}