帮助群友♂♂(AC),就是帮助自己
单调栈
- 单调递增栈:单调递增栈就是从栈底到栈顶数据是从小到大(一般)
- 单调递减栈:单调递减栈就是从栈底到栈顶数据是从大到小
E.g: 单调递增栈加入数据:::堆栈实现(栈顶为最大值)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| stack<int> st;
void _add(const int& x) { if (st.empty() || st.top() > x){ st.push(x); } else{ stack<int> tmp; while (!st.empty() && st.top() < x) { tmp.push(st.top()); st.pop(); } st.push(x); while (!tmp.empty()) { st.push(tmp.top()); tmp.pop(); } } }
|
E.g: 单调递增栈加入数据:::动态数组实现((๑•̀ㅂ•́)و✧)用数组实现的真的还是单调栈吗
可恶!已经完全不是堆栈的样子了
1 2 3 4 5 6 7 8 9 10 11 12 13
| vector<int> v;
void _add(const int& x) { v.insert(lower_bound(v.begin(), v.end(), x, greater<>()), x); }
void _add(const int& x) { v.insert(lower_bound(v.begin(), v.end(), x), x); }
|
其实堆栈没必要一定是堆栈**(๑•̀ㅂ•́)و✧**
然后对于洛谷的这一题 [COI2007] Patrik 音乐会的等待
题目描述
$n$ 个人正在排队进入一个音乐会。人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人。
队列中任意两个人 $a$ 和 $b$,如果他们是相邻或他们之间没有人比 $a$ 或 $b$ 高,那么他们是可以互相看得见的。
写一个程序计算出有多少对人可以互相看见。
输入格式
输入的第一行包含一个整数 $n$,表示队伍中共有 $n$ 个人。
接下来的 $n$ 行中,每行包含一个整数,表示人的高度,以毫微米(等于 $10^{-9}$ 米)为单位,这些高度分别表示队伍中人的身高。
输出格式
输出仅有一行,包含一个数 $s$,表示队伍中共有 $s$ 对人可以互相看见。
样例 #1
样例输入 #1
样例输出 #1
提示
数据规模与约定
对于全部的测试点,保证 $1\le$ 每个人的高度 $< 2^{31}$,$1 \le n \le 5\times 10^5$。
完全适合用单调栈(的概念)去做
上代码解释
注:这不是AC代码,它没有对大数据的情况进行处理,会卡TLE(代码运行超时)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
stack<int> st; int ans = 0;
void _add(const int& x) { int lap = 1; while (!st.empty() && x >= st.top()) { if (st.top() == x)lap++; ans++; st.pop(); }
if (!st.empty())ans++; while (lap--)st.push(x); }
int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; int x; while (n--) { cin >> x; _add(x); } cout << ans; return 0; }
|
注:这是AC代码
能过大数据的一大原因就在
代码第35行pa.second += st.top().second;
的操作
将相邻的同类数据给合并起来,而不是像上方的80分代码那样~~先pop再push~~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| #include <iostream> #include <stack> using namespace std;
stack< pair<int, long long> > st;
long long ans = 0;
int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; int x; while (n--) { cin >> x; pair<int, long long> pa(x, 1ll); while (!st.empty() && x >= st.top().first) { if (st.top().first == x){ pa.second += st.top().second; } ans += st.top().second;
st.pop(); }
if (!st.empty())ans++;
st.push(pa); }
cout << ans;
return 0; }
|