用双向链表维护可反悔贪心。
当堆顶<0后直接break。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N= 5e5 + 5 ;
int n, m, ans;
int a[ N] , l[ N] , r[ N] ;
bool vis[ N] ;
struct node
{
int id, v;
inline bool operator < ( const node & x) const
{
return x. v> v;
}
} ;
priority_queue< node> q;
signed main ( ) {
scanf ( "%lld%lld" , & n, & m) ;
for ( register int i= 1 ; i<= n; ++ i) scanf ( "%lld" , & a[ i] ) ;
for ( register int i= 1 ; i<= n; ++ i) l[ i] = i- 1 , r[ i] = i+ 1 ;
for ( register int i= 1 ; i<= n; ++ i) q. push ( ( node) { i, a[ i] } ) ;
while ( m-- )
{
while ( vis[ q. top ( ) . id] ) q. pop ( ) ;
if ( q. top ( ) . v< 0 ) break ;
node u= q. top ( ) ; q. pop ( ) ;
ans+ = u. v;
a[ u. id] = a[ l[ u. id] ] + a[ r[ u. id] ] - u. v;
q. push ( ( node) { u. id, a[ u. id] } ) ;
vis[ l[ u. id] ] = vis[ r[ u. id] ] = true ;
l[ u. id] = l[ l[ u. id] ] ; r[ u. id] = r[ r[ u. id] ] ;
r[ l[ u. id] ] = u. id; l[ r[ u. id] ] = u. id;
}
printf ( "%lld\n" , ans) ;
return 0 ;
}