社区讨论
85pts. 求调!!!(代码有注释)
P14962 [LBA-OI R2 A] 一次买够参与者 3已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mk9frxmv
- 此快照首次捕获于
- 2026/01/11 15:52 上个月
- 此快照最后确认于
- 2026/01/15 13:40 上个月
CPP
#include<cstdio>
#include<queue>
#define max(x,y) (x>y?x:y)
#define change(x) (x>n0?num[x-n0]:x) //类似于哈希函数。
using std::priority_queue;
const int N=4e5+1,M=2e5+1;
struct e
{
long i,t,w;//i为物品对应的数组下标,t为时间标记,w为性价比。
bool operator < (const e& a) const
{
return i==a.i?t<a.t:w<a.w;
}
};
long n,m,l,n0;//n0为初始时的数组长度。n,m,l如题。
long q;//总花费。
long v[N],w[N],num[M],sum[N];//sum存每个物品的最新的时间标记。v,w如题。
bool vis[N];//判断物品是否买过。
priority_queue<e> queue;//最大堆。
int main()
{
scanf("%d %d",&n,&m);
n0=n;
for(int i=1;i<=n;++i)
{
scanf("%d %d",v+i,w+i);
l=max(l,w[i]);
}
for(int i=1;i<=n;++i)
{
if(w[i]==l)
{
vis[i]=true;
q+=v[i];
}
else queue.push({i,0,w[i]});
}
for(int i=1,x,y,o;i<=m;++i)
{
scanf("%d %d %d",&o,&x,&y);
if(o==1)
{
num[i]=++n;
v[n]=x;
w[n]=y;
if(y>=l)
{
vis[n]=true;
q+=v[n];
}
else queue.push({n,i,y}),sum[n]=i;
}
else if(o==2)
{
w[change(x)]=y;
if(vis[change(x)])
{
if(l>y)
{
l=y;
while(queue.size()&&queue.top().w>=l)
{
auto u=queue.top();
queue.pop();
if(vis[u.i]||sum[u.i]!=u.t) continue;
if(w[u.i]>=l)
{
q+=v[u.i];
vis[u.i]=true;
}
}
}
}
else
{
if(y>=l) vis[change(x)]=true,q+=v[change(x)];
else queue.push({change(x),i,y}),sum[change(x)]=i;
}
}
printf("%ld\n",q);
}
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...