题解

2 条题解

  • 2
    @ 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;
    }
    
    
  • 0
    @ 2014-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 long

    int 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

信息

ID
1733
难度
4
分类
数据结构 点击显示
标签
递交数
226
已通过
91
通过率
40%
被复制
2
上传者