码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 332B B. Maximum Absurdity(rmq)

时间:2015-09-12 21:53:08      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:codeforces   rmq   dp   

题目链接:

codeforces 332B


题目大意:

给出一个序列,让找出不互相覆盖的两个长度为k的段,问在两个段的权值和最大的情况下,按照左边段的左端点排序,右边段的左端点作为第二关键字排序,得到的第一个答案。


题目分析:

  • 很水的数据结构的题目,我们只需要先利用前缀和预处理出所有长度为k的段的总权值。然后利用rmq维护区间最大值和得到这个最大值取得的段的最左位置。
  • 然后我们枚举第二段的位置,然后找到在采用当前段的前提下,第一段能取得的最大最左的情况,利用rmq的查询即可。

AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define MAX 200007

using namespace std;

typedef long long LL;
typedef pair<long long , int > PII;

int n,k;
LL a[MAX],b[MAX];
LL dp[MAX][30];
LL ans[MAX][30];

void make ( )
{
    for ( int i = 1 ; i <= n ; i++ )
    {
        dp[i][0] = b[i];
        ans[i][0] = i;
    }
    for ( int j = 1 ; (1<<j) <= n ; j++ )
        for ( int i = 1 ; i+(1<<j)-1 <= n ; i++ )
        {
            dp[i][j] = max ( dp[i][j-1] , dp[i+(1<<(j-1))][j-1] );
            if ( dp[i][j-1] == dp[i][j] ) ans[i][j] = ans[i][j-1];
            else ans[i][j] = ans[i+(1<<(j-1))][j-1];
        }
}

PII query ( int l , int r )
{
   int k = (int)((log((r-l+1)*1.0))/log(2.0));
   LL maxn;
   int temp;
   maxn = max ( dp[l][k] , dp[r-(1<<k)+1][k] );
   if ( maxn == dp[l][k] ) temp = ans[l][k];
   else temp = ans[r-(1<<k)+1][k];
   return make_pair ( maxn , temp ); 
}

int main ( )
{
    while ( ~scanf ( "%d%d" , &n , &k ) )
    {
        a[0] = 0;
        for ( int i = 1 ; i <= n ; i++ )
        {
            scanf ( "%lld" , &a[i] );
            a[i] += a[i-1];
        }
        for ( int i = k ; i <= n ; i++ )
            b[i] = a[i]-a[i-k];
        make ( );
        int loc =-1;
        PII temp = make_pair ( 0 , 0 );
        for ( int i = 2*k ; i <= n ; i++ )
        {
           PII tmp = query ( k , i-k );
           if ( tmp.first + b[i] > temp.first )
           {
               temp = tmp;
               temp.first += b[i];
               loc = i;
           }
        }
        temp.second -= k-1;
        loc -= k-1;
        printf ( "%d %d\n" , (int)temp.second , loc ); 
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

codeforces 332B B. Maximum Absurdity(rmq)

标签:codeforces   rmq   dp   

原文地址:http://blog.csdn.net/qq_24451605/article/details/48395225

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!