专栏文章

题解: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 内元素键的数量是唯一的便),于查找和删除。
我们可以用一条双向链表储存每个数据的前驱和后继。用 ansans 代表栈内相邻元素和是奇数的组数。每次向链表里添加元素时,先判断在 map 里有无重复元素(jj)。如果有,分三种情况:
  1. jj 是链表第一个元素,那么它只对后面的 ansans 有贡献,所以将它对后面的贡献减去。
  2. jj 是链表当前的最后一个元素,那么它只对前面的 ansans 有贡献,所以将它对后面的贡献减去。
  3. jj 是链表中间的元素,那么它对前面和后面的 ansans 都有贡献,所以都减去。如果被删除后 jj 前面和后面的两个数和是奇数,那么 ansans 应加 11
判断完成后将新元素添加到链表中,并计算新元素对答案的贡献。最后输出。
于是我们就快乐的通过了这道题 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 条评论,欢迎与作者交流。

正在加载评论...