弱智问题求助
查看原帖
弱智问题求助
255169
__LePetitPrince__楼主2023/11/1 16:50

以下问题可能十分弱智,大佬们轻喷谢谢

  1. 我大概对单调栈理解的有问题,tj 里都是构造一个单调递减的栈,从左往右算一遍,但是我觉得这样难道不是只能统计 可以互相看见的人对 中左边的人比右边的人高的情况吗?我自己写的本来是从左往右算一遍再从右往左算一遍(计算 可以互相看见的人对 中右边的人比左边的人高的情况)的,确实错了,但请问为什么可以只统计一遍呢?

  2. 我觉得如这篇题解这样做最坏会出现 O(n2)O(n^2) 的情况(相同的数字反复弹出又压入),于是我这样处理了连续的相同数字的情况(可以看到把从右往左算的注释掉了),统计一下连续的数字个数,放入 b 数组,再对 b 数组进行单调栈的做法,但是 WA 20pts,我不理解为什么错了,求大佬指教 Orz:

#include <stdio.h>
#include <stack>
#include <vector>
using namespace std;
const int S = 5e5 + 5;
typedef pair<int, int> P;
int n, a[S], h[S];
P b[S];
long long ans;
stack<int> st;
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		h[i] = i;
	}
	for (int i = 1; i <= n; i++) {
		if (a[i] == a[i - 1]) {
			h[i] = h[i - 1];
		}
	}
	int cnt = 0;
	for (int i = 1; i <= n; i++) {
		if (h[i] != h[i - 1]) {
			cnt++;
			b[cnt].first = a[i];
			b[cnt].second = 1;
		} else {
			b[cnt].second++;
		}
	}
	for (int i = 1; i <= cnt; i++) {
		while (!st.empty() && b[st.top()].first < b[i].first) {
			ans += (b[st.top()].second * b[i].second);
			st.pop();
		}
		if (!st.empty()) {
			ans += b[st.top()].second * b[i].second;
		}
		st.push(i);
	}/*
	while (!st.empty()) {
		st.pop();
	}
	for (int i = cnt; i >= 1; i--) {
		while (!st.empty() && b[st.top()].first < b[i].first) {
			ans += b[st.top()].second;
			st.pop();
		}
		if (!st.empty()) {
			ans++;
		}
		st.push(i);
	}*/
	printf("%lld", ans);
	return 0;
}
  1. (大致同 https://www.luogu.com.cn/discuss/555138)原帖已经有人回答了,但是我没有看懂,有大佬能再详细解释下吗 UwU

球球了

2023/11/1 16:50
加载中...