# 你相信引力吗？（一道单调栈的题）

//有两份代码，第一份是我的（单调栈写的比较丑，有点慢，用了离散化，找以第一个点作为右端点的满足条件的点对时用的第一种方法），第二份是同学的（找以第一个点作为右端点的满足条件的点对时用的第二种方法）。

#include<bits/stdc++.h>
using namespace std;
int n, vis[5000005], a[5000005] ,ma, wcma, wma, cma ,b[5000005], zhan[5000005], top, tp,  len[5000005], cnt, sval[5000005], ans;
int main()
{
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
if(a[i] > ma)
{
ma = a[i];   wma = i;
}
}
for(int i = wma; i <= n; i++)
{
b[++cnt] = a[i];    sval[cnt] = a[i];
}
for(int i = 1; i < wma;i++)
{
b[++cnt] = a[i];   sval[cnt] = a[i];
}
sort(sval+1,sval+1+n);
cma = sval[n-1];
int m = unique(sval+1,sval+1+n) - sval - 1;
for(int i = 1; i <= cnt; i++)
{
b[i] = lower_bound(sval+1,sval+1+m,b[i]) - sval;
}
cma = lower_bound(sval+1,sval+1+m,cma) - sval;
zhan[++top] = b[1];
vis[b[1]]++;
for(int i = 2; i <= cnt; i++)
{
while(top && (zhan[top] < b[i]))
{
ans ++;
vis[zhan[top]]--;
top--;
}
if(zhan[top] == b[i] && top)
{
ans += vis[zhan[top]];
if(top - vis[zhan[top]] > 0) ans ++;
vis[zhan[top]]++;  zhan[++top] = b[i];
}
else
{
if(top)ans++;	zhan[++top] = b[i]; vis[b[i]]++;
}
}
int ha = 0;
for(int i = n; i >=2; i--)
{
if(b[i] == cma) break;
if(b[i] >= ha)
{	ans++;   	ha = b[i];}
}
cout << ans;
return 0;
} 
#include<bits/stdc++.h>
using namespace std;

const int N = 5000005;
int n, a[N] ,ma, wma, b[N], top, cma[N], tp,  len[N], cnt, sval[N], ans, tmp[N], lma[N], rma[N];
struct node {
int size, val;
node(int val = 0, int size = 0): size(size), val(val) {}
}zhan[N];

int main()
{
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
if(a[i] > ma)
{
ma = a[i];
wma = i;
}
}
for(int i = wma; i <= n; i++)
{
b[++cnt] = a[i];
}
for(int i = 1; i < wma;i++)
{
b[++cnt] = a[i];
}
for(int i = 2;i <= n;i ++) {
if(b[i] >= tmp[i - 1]) lma[i] = 1, tmp[i] = b[i];
else tmp[i] = max(tmp[i], tmp[i - 1]);
} memset(tmp, 0, sizeof(tmp));
for(int i = n;i >= 1;i --) {
if(b[i] >= tmp[i + 1]) rma[i] = n, tmp[i] = b[i];
else tmp[i] = max(tmp[i], tmp[i + 1]);
}
zhan[++top] = node(b[1], 1);
for(int i = 2; i <= n; i++)
{
while(zhan[top].val < b[i] && top)
{
ans += zhan[top].size;
top--;
}
if(b[i] == zhan[top].val) {
ans += zhan[top].size; zhan[top].size ++;
if(top > 1) ans ++; continue;
}
if(top) ans ++;
zhan[++top] = node(b[i], 1);
}
int tp = 0;
for(int i = 2;i <= n;i ++) if(lma[i] != 1 && rma[i] == n) ans ++;
cout << ans;
return 0;
}