[BZOJ2151]种树

同1150
每次取最大,然后把val[l]+val[r]-val[now]放入堆中
/**************************************************************
    Problem: 2151
    User: momoka
    Language: C++
    Result: Accepted
    Time:404 ms
    Memory:6432 kb
****************************************************************/
 
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;++i)
#define drep(i,t,s) for(int i=t;i>=s;--i)
#define inf 0x3f3f3f3f
using namespace std;
 
inline int read(){
    char ch=getchar();
    int f=1,x=0;
    while (!(ch>='0' && ch<='9')) { if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0' && ch<='9') { x=x*10+(ch-'0'); ch=getchar();}
    return x*f;
}
int n,m,val[200500],l[200500],r[200500],ans;
bool mark[200500];
typedef pair<int,int>ele;
priority_queue<ele>q;
int main(){
  //freopen("xx.in","r",stdin);
  //freopen("xx.out","w",stdout);
  n=read(); m=read();
  if (m>(n>>1)){ puts("Error!"); return 0; }
  rep(i,1,n){
    val[i]=read();
    q.push(make_pair(val[i],i));
    l[i]=i-1;
    r[i]=i+1;
  }
  l[1]=n; r[n]=1;
  rep(i,1,m){
    while (mark[q.top().second]) q.pop();
    ele now=q.top();
    int id=now.second;
    q.pop();
    ans+=now.first;
    int ls=l[id],rs=r[id];
    mark[ls]=1,mark[rs]=1;
    l[id]=l[ls]; r[l[id]]=id;
    r[id]=r[rs]; l[r[id]]=id;
    val[id]=val[ls]+val[rs]-now.first;
    q.push(make_pair(val[id],id));
  }
  printf("%d\n",ans);
 // getchar(); getchar();
  //fclose(stdin); fclose(stdout);
  return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值