【题解】洛谷P12085

题目传送门

借鉴这篇题解,dalao%%%

如果我们真的模拟的话肯定过不了的(记录)。

所以我们可以使用链表+优先队列的方式,来记录这个数列。

其中的删除操作也不是让我们真的删去,用版本(version)的方式记录当前数据能不能用,不能用就弹出。

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <bits/stdc++.h>
using namespace std;
const int MAXN=500010;
#define int long long
int n,k;
int a[MAXN];
struct LIST
{
int pre,nxt;
}lst[MAXN];
struct node
{
int id;
int val;
int ver;
bool operator <(const node &a)const
{
if(val==a.val)return id>a.id;
else return val>a.val;
}
};
priority_queue <node> q;
int v[MAXN];
bool isdel[MAXN];//是否删除
int read()
{
int x=0,f=1;
char c=getchar();
while(!isdigit(c))
{
if(c=='-')f=-1;
c=getchar();
}
while(isdigit(c))
{
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
void print(int x)
{
if(x<0)x=-x;
if(x<10)putchar(x+'0');
else print(x/10),putchar(x%10+'0');
}
signed main()
{
n=read(),k=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
q.push({i,a[i],0});
lst[i]={i-1,i+1};//链表
}
lst[1].pre=lst[n].nxt=-1;
for(int vers=1;vers<=k;vers++)
{
while(!q.empty()&&q.top().ver!=v[q.top().id])q.pop();//过期的数据弹出
node front=q.top();
q.pop();
int id=front.id;
isdel[id]=1;
int val=front.val;
int pre=lst[id].pre,nxt=lst[id].nxt;
if(pre!=-1)
{
lst[pre].nxt=nxt;
a[pre]+=val;
q.push({pre,a[pre],vers});
v[pre]=vers;
}
if(nxt!=-1)
{
lst[nxt].pre=pre;
a[nxt]+=val;
q.push({nxt,a[nxt],vers});
v[nxt]=vers;
}
}
for(int i=1;i<=n;i++)
if(!isdel[i])printf("%lld ",a[i]);
return 0;
}

【题解】洛谷P12085
http://j27egu.github.io/2025/08/31/【题解】洛谷P12085/
作者
j27eGU
发布于
2025年8月31日
许可协议