标签:codeforces rmq dp
给出一个序列,让找出不互相覆盖的两个长度为k的段,问在两个段的权值和最大的情况下,按照左边段的左端点排序,右边段的左端点作为第二关键字排序,得到的第一个答案。
#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