题解:P12085 [蓝桥杯 2023 省 B] 整数删除
思路
把初始元素保存成
做法
双向链表
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 5e5 + 10;
struct node {
ll val;//值
int id;//下标
} a[N];
priority_queue<node>q;
int l[N], r[N], n, m;
int vis[N];//表示某个节点是否被删掉
bool operator < (node other, node top) {
//按val小的优先,val相等按id小的优先
if (other.val == top.val)
return top.id < other.id;
return top.val < other.val;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i].val;
a[i].id = i;
q.push(a[i]);
}
//0作为头结点,n+1作为尾节点
r[0] = 1, l[n + 1] = n;
for (int i = 1; i <= n; i++) {//双向链表初始化
l[i] = i - 1, r[i] = i + 1;
}
while (m--) { // 根据下标找到的val和队列的val不一致 或已经被删除过了
while (a[q.top().id].val != q.top().val || vis[q.top().id]) {
q.pop();
}
auto p = q.top().id; //这个一定是最新的
// cout << a[p].val << "<-val \n";
q.pop();
int left = l[p], right = r[p];
a[left].val += a[p].val, a[right].val += a[p].val; //左右加和
vis[p] = 1;
r[left] = right, l[right] = left; //链表的更新
if (left >= 1)
q.push(a[left]);//不是虚拟节点
if (right <= n)
q.push(a[right]);//不是虚拟节点
}
int p = r[0];
while (p != n + 1) {
cout << a[p].val << " ";
p = r[p];
}
}