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;
}
*/