http://www.rqnoj.cn/Problem_460.html
題意:n個人站成一隊,每兩個人之間如果沒有比一個高的就說明二者能互相看到,問有多少對人能互相看到對方。。
分析:單調隊列,沒的說。。。但是相同高度要特殊處理一下, 這裏我是將連續的相同高度的存到一起並記錄個數。。連續相同高度的這一堆肯定互相能看到,而且都能看到前面和後面的。。。
代碼:
#include<iostream>
using namespace std;
const int N=600010;
int n, a[N], q[N], qn;
int main()
{
int i, j, k, x, ans;
while(scanf("%d", &n)!=EOF)
{
qn = 0;
ans = 0;
for(i=0; i<n; i++)
{
scanf("%d", &x);
while(qn>=1 && x>q[qn-1])
{
ans += a[qn-1]*(a[qn-1]-1)/2;
if(qn>=2)
ans += a[qn-1];
ans += a[qn-1];
qn--;
}
if(qn!=0 && x==q[qn-1])
a[qn-1]++;
else
{
a[qn] = 1;
q[qn++] = x;
}
}
while(qn>=2)
{
ans += a[qn-1]*(a[qn-1]-1)/2;
ans += a[qn-1];
qn--;
}
ans += a[0]*(a[0]-1)/2;
printf("%d\n", ans);
}
return 0;
}
/*
#include<iostream>
using namespace std;
const int N=500100;
int n, a, sum;
int q[N], head, tail;
int main()
{
int i, j, k;
scanf("%d", &n);
head = tail = 0;
sum = 0;
for(i=0; i<n; i++)
{
scanf("%d", &a);
while(head<tail && q[tail-1]<a)
{
sum++;
tail--;
for(j=tail-1; j>head && q[j]==q[tail]; j--)
sum++;
if(tail>head)
sum++;
}
q[tail++] = a;
}
while(tail>head+1)
{
//sum++;
tail--;
for(j=tail-1; j>head && q[j]==q[tail]; j--)
sum++;
if(tail>head)
sum++;
}
printf("%d\n", sum);
return 0;
}
*/