专栏文章
题解:P12288 [蓝桥杯 2024 国 Java A] 栈
P12288题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mip2cxqg
- 此快照首次捕获于
- 2025/12/03 05:01 3 个月前
- 此快照最后确认于
- 2025/12/03 05:01 3 个月前
P12288 题解
核心:双向链表维护栈内数据,用 map 维护每个数出现的次数和位置(因为 map 内元素键的数量是唯一的便),于查找和删除。
我们可以用一条双向链表储存每个数据的前驱和后继。用 代表栈内相邻元素和是奇数的组数。每次向链表里添加元素时,先判断在 map 里有无重复元素()。如果有,分三种情况:
- 是链表第一个元素,那么它只对后面的 有贡献,所以将它对后面的贡献减去。
- 是链表当前的最后一个元素,那么它只对前面的 有贡献,所以将它对后面的贡献减去。
- 是链表中间的元素,那么它对前面和后面的 都有贡献,所以都减去。如果被删除后 前面和后面的两个数和是奇数,那么 应加 。
判断完成后将新元素添加到链表中,并计算新元素对答案的贡献。最后输出。
于是我们就快乐的通过了这道题 QAQ。
AC code:
CPP#include <bits/stdc++.h>
using namespace std;
#define int long long
int n;
const int N = 5e5 + 10;
const int M = 1e6 + 10;
struct node{
int prev, nxt, id;
}a[N];
map<int, int> num;
int ans = 0, cnt = 2;
inline void add(int k, int x){
a[cnt].id = x;
a[cnt].nxt = a[k].nxt;
a[a[k].nxt].prev = cnt;
a[cnt].prev = k;
a[k].nxt = cnt;
cnt++;
}
signed main(){
cin >> n;
a[0].nxt = 1;
a[1].prev = 0;
for (int i = 1; i <= n; i++){
int x;
cin >> x;
int j = 0;
if (num[x]){
j = num[x];
int pre = a[j].prev;
int next = a[j].nxt;
if (pre) ans -= (a[pre].id + a[j].id) % 2;
if (next != 1) ans -= (a[next].id + a[j].id) % 2;
if (next != 1 && pre != 0) ans += (a[next].id + a[pre].id) % 2;
a[a[j].prev].nxt = a[j].nxt;
a[a[j].nxt].prev = a[j].prev;
}
num[x] = i + 1;
add(a[1].prev, x);
j = num[x];
if (a[j].prev) ans += (a[j].id + a[a[j].prev].id) % 2;
cout << ans << "\n";
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...