rqnoj 460单调队列-1

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


你可能感兴趣的:(rqnoj 460单调队列-1)