2 条题解
-
23159968027 LV 9 @ 2019-01-27 20:09:52
#include <algorithm> #include <cstring> #include <queue> #include <cstdio> #define For(i,l,r) for(int i=l;i<=r;i++) #define N 500005 #define ll long long using namespace std; //核心思想:前缀和+st表+堆+二分(注意细节!) struct node{ int i,l,r,val,pos;//i为起始位置,pos为最终位置,val为i为起始位置时最大值 bool operator < (const node& a) const{return val<a.val;} }; int posi[N][25],f[N],Log2[N]; int n,k,L,R; inline int Max(int x,int y) {return f[x]>f[y]? x:y;} void ST(){ Log2[0]=-1; for(int i=1;i<=n;i++) if((i&(i-1))==0) Log2[i]=Log2[i-1]+1; else Log2[i]=Log2[i-1]; for(int i=1;i<=n;i++) posi[i][0]=i; for(int j=1;(1<<j)<=n;j++) for(int i=1;i+(1<<j)<=n+1;i++){ posi[i][j]=Max(posi[i][j-1],posi[i+(1<<(j-1))][j-1]); } } inline int RMQ(int l,int r){ int tmp=Log2[r-l+1]; return Max(posi[l][tmp],posi[r-(1<<tmp)+1][tmp]); } inline int read() { int res=0,f=1; char ch=getchar(); while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} while (ch>='0' && ch<='9') {res=res*10+ch-'0'; ch=getchar();} return res*f; } priority_queue <node> q; int main(){ n=read();k=read();L=read();R=read(); For(i,1,n) f[i]=f[i-1]+read();//前缀和 ST();//初始化st表 For(i,1,n+1-L){ int pos=RMQ(i+L-1,min(n,i+R-1));//终点位置 q.push((node){i,i+L-1,min(n,i+R-1),f[pos]-f[i-1],pos});//进入堆 } ll ans=0; //二分 while(k){ node x=q.top(); q.pop(); k--; ans+=(ll)x.val; node ls=x,rs=x; ls.r=x.pos-1;rs.l=x.pos+1; if(ls.r>=ls.l){ ls.pos=RMQ(ls.l,ls.r); ls.val=f[ls.pos]-f[ls.i-1]; q.push(ls); } if(rs.r>=rs.l){ rs.pos=RMQ(rs.l,rs.r); rs.val=f[rs.pos]-f[rs.i-1]; q.push(rs); } } printf("%lld\n",ans); return 0; }
-
02014-01-29 16:58:54@
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>using namespace std ;
#define MAXN 1000100
#define MAXD 24
#define rep( i , x ) for ( int i = 0 ; i ++ < x ; )
#define ll long longint a[ MAXN ] , n , k , pre[ MAXN ] , st[ MAXN ][ MAXD ] , D , L , R ;
int pos[ MAXN ][ MAXD ] ;int Min( int l , int r ) {
int d = int( log2( r - l + 1 ) ) ;
return min( st[ l ][ d ] , st[ r - ( 1 << d ) + 1 ][ d ] ) ;
}int Pos( int l , int r ) {
int d = int( log2( r - l + 1 ) ) ;
if ( st[ l ][ d ] < st[ r - ( 1 << d ) + 1 ][ d ] ) {
return pos[ l ][ d ] ;
} else return pos[ r - ( 1 << d ) + 1 ][ d ] ;
}struct node {
int l , r , x ;
ll v ;
node( int _l , int _r , int _x ) : l( _l ) , r( _r ) , x( _x ) , v( pre[ _x ] - Min( _l , _r ) ) {}
bool operator < ( const node &a ) const {
return v < a.v ;
}
};
priority_queue < node > q ;void Init( ) {
scanf( "%d%d%d%d" , &n , &k , &L , &R ) ;
rep( i , n ) scanf( "%d" , &a[ i ] ) ;
pre[ 0 ] = 0 ;
rep( i , n ) pre[ i ] = pre[ i - 1 ] + a[ i ] ;
D = int( log2( n ) ) + 1 ;
for ( int i = 0 ; i <= n ; ++ i ) {
st[ i ][ 0 ] = pre[ i ] , pos[ i ][ 0 ] = i ;
}
rep( i , D ) {
for ( int j = 0 ; j <= n ; ++ j ) {
if ( st[ j ][ i - 1 ] < st[ j + ( 1 << ( i - 1 ) ) ][ i - 1 ] ) {
st[ j ][ i ] = st[ j ][ i - 1 ] , pos[ j ][ i ] = pos[ j ][ i - 1 ] ;
} else {
st[ j ][ i ] = st[ j + ( 1 << ( i - 1 ) ) ][ i - 1 ] ;
pos[ j ][ i ] = pos[ j + ( 1 << ( i - 1 ) ) ][ i - 1 ] ;
}
}
}
while ( ! q.empty( ) ) q.pop( ) ;
for ( int i = 0 ; i ++ < n ; ) {
int l = max( 0 , i - R ) , r = i - L ;
if ( r < 0 ) continue ;
q.push( node( l , r , i ) ) ;
}
}void Solve( ) {
ll ans = 0 ;
while ( k -- ) {
node ret = q.top( ) ; q.pop( ) ;
ans += ret.v ;
int p = Pos( ret.l , ret.r ) ;
if ( ret.l < p ) q.push( node( ret.l , p - 1 , ret.x ) ) ;
if ( ret.r > p ) q.push( node( p + 1 , ret.r , ret.x ) ) ;
}
printf( "%lld\n" , ans ) ;
}int main( ) {
Init( ) ;
Solve( ) ;
return 0 ;
}
- 1