You are given a permutation p of n integers 1, 2, …, n (a permutation is an array where each element from 1 to n occurs exactly once).
Let’s call some subsegment p[l,r] of this permutation special if pl+pr=maxi=lrpi. Please calculate the number of special subsegments.
Input
The first line contains one integer
n
(
3
≤
n
≤
2
⋅
1
0
5
)
.
n (3≤n≤2⋅10^5).
n(3≤n≤2⋅105).
The second line contains n integers p1, p2, …, pn (1≤pi≤n). All these integers are pairwise distinct.
Output
Print the number of special subsegments of the given permutation.
Examples
Input
5
3 4 1 5 2
Output
2
Input
3
1 3 2
Output
1
思路:这题其实我觉得也挺简单的,暴力一点的思路就我们先看整个区间的最大值的位置,然后枚举在他的右边的元素,然后减一下就得到了左边的元素的大小,然后看他的位置是否在他的左边。并不是每次都枚举右边,看那边元素个数小就枚举哪边,那么这样的操作就可以优化到
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)次。
那么得到区间最大值的位置就显然是rmq了,那么元素在那个位置,我们用一个数组存一下就行,就可以
O
(
1
)
O(1)
O(1)了 ,总复杂度为
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#define INF 0x7f7f7f7f
#define maxx 200005
#define mod 1000000007
using namespace std;
typedef long long ll;
int a[maxx];
int b[maxx];
int n;
int f[maxx][20];
void init()
{
int N=ceil(log2(n));
for(int i=1;i<=n;i++)f[i][0]=i;
for(int i=1;i<=N;i++)
{
for(int j=1;j<=n;j++)
{
f[j][i]=f[j][i-1];
if(j+(1<<(i-1))<=n&&a[f[j][i]]<a[f[j+(1<<(i-1))][i-1]])
f[j][i]=f[j+(1<<(i-1))][i-1];
}
}
}
int query(int l,int r)
{
int t=log2(r-l+1);
if(a[f[l][t]]>a[f[r-(1<<t)+1][t]])return f[l][t];
else return f[r-(1<<t)+1][t];
}
int ans=0;
void solve(int l,int r)
{
if(r-l+1<3)return;
int mid=query(l,r);
int left=mid-l;
int right=r-mid;
if(left>right)
{
for(int i=mid+1;i<=r;i++)
{
int now=a[mid]-a[i];
if(l<=b[now]&&b[now]<mid)ans++;
}
}
else
{
for(int i=l;i<mid;i++)
{
int now=a[mid]-a[i];
if(mid<b[now]&&b[now]<=r)ans++;
}
}
solve(l,mid-1);
solve(mid+1,r);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",a+i);
b[a[i]]=i;
}
init();
solve(1,n);
cout<<ans<<endl;
return 0;
}