对数组从左往右遍历得到
l
e
f
t
[
i
]
left[i]
left[i],对数组从右往左遍历得到
r
i
g
h
t
[
i
]
right[i]
right[i]。
总体思路:
l
e
f
t
[
i
]
left[i]
left[i] : 左边第一个大于
v
[
i
]
v[i]
v[i]的坐标
r
i
g
h
t
[
i
]
right[i]
right[i]: 右边第一个大于
v
[
i
]
v[i]
v[i]的坐标
s
a
m
e
[
i
]
same[i]
same[i]:
[
l
e
f
t
[
i
]
,
i
)
[left[i], i)
[left[i],i) 这个区间内和
v
[
i
]
v[i]
v[i]这个值相等的个数
最后结果是
(
i
,
l
e
f
t
[
i
]
)
(i, left[i])
(i,left[i]) 为一对,
(
i
,
r
i
g
h
t
[
i
]
)
(i, right[i])
(i,right[i]) 为一对,这里
l
e
f
t
[
i
]
=
=
0
left[i] == 0
left[i]==0 和
r
i
g
h
t
[
i
]
=
=
n
+
1
right[i] == n + 1
right[i]==n+1为同一种情况。再加上
s
a
m
e
[
i
]
same[i]
same[i]。
计算:
求
l
e
f
t
[
i
]
,
r
i
g
h
t
[
i
]
left[i], right[i]
left[i],right[i],典型的单调栈
求
s
a
m
e
[
i
]
same[i]
same[i] 就是碰到左边第一个相等
j
j
j 的时候,就是
s
a
m
e
[
i
]
=
s
a
m
e
[
j
]
+
1
same[i] = same[j] + 1
same[i]=same[j]+1
代码
#include<cstdio>#include<iostream>#include<algorithm>#include<cmath>#include<string>#include<vector>#include<cstring>#include<map>#include<stack>usingnamespace std;typedeflonglong llong;intmain(){
std::ios::sync_with_stdio(false);//没有会Tint n;
cin >> n;
vector<int>v(n);for(int i =0; i < n; i++)
cin >> v[i];rotate(v.begin(),max_element(v.begin(), v.end()), v.end());
v.push_back(v[0]);//for (int i = 0; i <= n; i++)// cout << v[i] << endl;
vector<int>left(n +1);
vector<int>right(n +1);
vector<int>same(n +1,0);
stack<int> s;
s.push(0);
left[0]=-1;for(int i =1; i < n; i++){while(!s.empty()&& v[s.top()]<= v[i]){if(v[s.top()]== v[i])
same[i]= same[s.top()]+1;
s.pop();}if(s.empty())
left[i]=-1;else
left[i]= s.top();
s.push(i);}while(!s.empty())
s.pop();
s.push(n);
right[n]= n;for(int i = n -1; i >=1; i--){while(!s.empty()&& v[s.top()]<= v[i])
s.pop();if(s.empty())
right[i]= n +1;else
right[i]= s.top();
s.push(i);}//for (int i = 1; i < n; i++)// printf("left[%d]=%d right[%d]=%d same[%d]=%d\n", i, left[i], i, right[i], i, same[i]);
llong ans =0;for(int i =1; i < n; i++){if(left[i]!=-1)
ans++;if(right[i]!= n +1)
ans++;if(left[i]==0&& right[i]== n)
ans--;
ans += same[i];}
cout << ans << endl;return0;}