您的位置:首页 > 其它

(3486)HDU

2015-06-04 19:55 288 查看
#include<iostream>

#include<cstdio>

#include<string.h>

#include<cstring>

#include<string>

#include<stack>

#include<set>

#include<algorithm>

#include<cmath>

#include<vector>

#include<map>

#define LOCAL

#define ll long long

#define lll unsigned long long

#define MAX 200010

#define eps 1e-8

#define INF 0x7fffffff

#define mod 1000000007

using namespace std;

/*

题意:问你分成X区间,x最小的情况下,取每个区间的最大值,求和,大于K

想法:枚举区间长度和个数 二分+RMQ

PS:http://m.blog.csdn.net/blog/dr5459/9936607

*/

int n;

int a[MAX];

int dp[MAX][30];

void RMQ_init()//初始化

{

for(int i=0;i<n;i++)

dp[i][0] = a[i];

for(int j=1;(1<<j)<=n;j++)

{

for(int i=0;i+(1<<j)-1<n;i++)

dp[i][j] = max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);

}

}

//查询函数

int RMQ(int L,int R)

{

int k=0;

while(1<<(k+1)<=R-L+1)k++;

return max(dp[L][k],dp[R-(1<<k)+1][k]);

}

bool solve(int len,int k,int s)

{

int sum = 0;

for(int i = 1; i<=s; i++)

{

int l = (i - 1)*len ;

int r = len*i - 1;

sum+=RMQ(l,r);

if(sum>k)

return 1;

}

return 0;

}

int main()

{

// freopen("date.in","r",stdin);

int k;

while(~scanf("%d%d",&n,&k))

{

int sum = 0;

if(n==-1&&k==-1)break;

for(int i =0; i<n; i++)

{

scanf("%d",&a[i]);

sum+=a[i];

}

if(sum<=k)

{

puts("-1");

continue;

}

RMQ_init();

int ans;

int l = 1;

int r = n;

while(l<=r)

{

int mid = (l+r)>>1;

if(solve(n/mid,k,mid))

{

ans = mid;

r = mid - 1;

}

else

l = mid + 1;

}

printf("%d\n",ans);

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: