刚学OI的萌新袜子求助
  • 板块P1484 种树
  • 楼主itisover
  • 当前回复6
  • 已保存回复6
  • 发布时间2020/11/1 21:49
  • 上次更新2023/11/5 09:15:20
查看原帖
刚学OI的萌新袜子求助
186045
itisover楼主2020/11/1 21:49

我的想法:每次贪心求出当前最优后,删除当前点,并插入一个新点,点权就是题解的那样,以此用来反悔。当优先队列中的最大值已经是负数了,就没有必要选点了,就break掉

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=5e5+5;
int n,k,a[N<<1],cnt,ans;
int l[N<<1],r[N<<1],vis[N<<1];
struct IloveCCF{
  int id,val;
  bool operator <(const IloveCCF &x) const{
    return val<x.val;
  }
}node[N<<1];
priority_queue<IloveCCF> q;
inline int read(){
  int ans=0,f=1;char ch=getchar();
  while(!isdigit(ch)){if(ch=='-') f=-f;ch=getchar();}
  while(isdigit(ch)){ans=(ans<<3)+(ans<<1)+ch-'0';ch=getchar();}
  return ans*f;
}
signed main(){
  cnt=n=read(),k=read();
  for(int i=1;i<=n;i++){
    a[i]=read();
    l[i]=i-1,r[i]=i+1;
    q.push((IloveCCF){i,a[i]});
  }
  r[n]=1;l[1]=n;
  for(int i=1;i<=k;i++){
    while(vis[q.top().id]) q.pop();
    int id=q.top().id,val=q.top().val;
    q.pop();
    if(val<0) break;
    ans+=val;
    ++cnt;
    vis[l[id]]=vis[r[id]]=1;
    l[r[r[id]]]=cnt,r[l[l[id]]]=cnt;
    l[cnt]=l[l[id]],r[cnt]=r[r[id]];
    a[cnt]=a[l[id]]+a[r[id]]-val; 
    q.push((IloveCCF){cnt,a[cnt]});
  }
  printf("%lld",ans);
  return 0;
}

n=3e5,k=8e4的点挂掉了

我输出66833080378

标程输出66833112691

2020/11/1 21:49
加载中...