版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38013346/article/details/82108894
题目
题解
网上很多使用二分的方法
其实是不对的,我们可以讨论一下二分为什么不对。
乍一看没什么不对,选的人多了嘛,肯定能力和越大。
可是实际上并不满足这个性质,因为题目是从一段中选出一个最大的。
那么接下来就来讨论正确的做法
时间复杂度为
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
typedef long long ll;
int arr[maxn],mm[maxn];
int n;ll k;
struct ST{
int dp[maxn][20];
void init() {
mm[0] = -1;
for(int i=0;i<n;i++) {
dp[i][0] = arr[i];
mm[i+1] = (((i+1) & i) == 0) ? mm[i] + 1 : mm[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 query(int l,int r) {
int k = mm[r-l+1];
// while((1<<(k+1)) <= (r - l + 1)) k++;
return max(dp[l][k],dp[r-(1<<k)+1][k]);
}
}st;
int solve() {
st.init();
for(int m=2;m<=n;) {
int len = n / m,c = 1,l;
int r = n / len;
ll res = 0;
for(;m<=r;m++) {
for(;c<=m;c++) {
l = c * len;
res += st.query(l-len,l-1);
if(res > k) return m;
}
}
}
return -1;
}
int main()
{
while(~scanf("%d%lld",&n,&k),n != -1 && k != -1) {
ll sum = 0;
int tmp = 0;
for(int i=0;i<n;i++) {
scanf("%d",&arr[i]);
sum += arr[i];
tmp = max(tmp,arr[i]);
}
if(sum <= k) {
printf("-1\n");
continue;
}
if(tmp > k) {
printf("1\n");
continue;
}
printf("%d\n",solve());
}
return 0;
}