考虑区间l,r,最大值在mid(倍增),枚举长度小的一边,然后分治(l,mid-1)(mid+1,r)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
using namespace std;
int n;
struct node
{
int v,id;
friend bool operator<(node x,node y)
{
return x.v>y.v;
}
}itm[200005];
long long ans;
int a[200005],pos[200005];
int dp[800005][20];
int fac[20];
int get(int l,int r)
{
int len=log2(r-l+1);
return max(dp[l][len],dp[r-fac[len]+1][len]);
}
void dfs(int l,int r)
{
if(r-l+1<=2)
return ;
int sta=get(l,r);
int mid=pos[sta];
if(mid==l)
dfs(l+1,r);
else if(mid==r)
dfs(l,r-1);
else
{
int l1=l,r1=mid-1,l2=mid+1,r2=r;
if(r2-l2<r1-l1)
swap(l1,l2),swap(r1,r2);
for(int i=l1;i<=r1;i++)
{
int tp=pos[sta-a[i]];
if(tp>=l2 && tp<=r2)
ans++;
}
dfs(l1,r1);dfs(l2,r2);
}
}
int main() {
fac[0]=1;
for(int i=1;i<20;i++)
fac[i]=2*fac[i-1];
while(~scanf("%d",&n))
{
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
int tp;
scanf("%d",&tp);
a[i]=tp;
pos[tp]=i;
itm[i].v=tp;itm[i].id=i;
dp[i][0]=tp;
}
sort(itm+1,itm+1+n);
for(int i=1;i<20;i++)
{
for(int j=1;j<=n;j++)
{
if(j+fac[i]-1>n)
break;
dp[j][i]=max(dp[j][i-1],dp[j+fac[i-1]][i-1]);
}
}
ans=0;
dfs(1,n);
printf("%lld\n",ans);
}
return 0;
}