hdu3486 ST表区间最值+二分

 还是挺简单的,但是区间处理的时候要注意一下

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 200005
#define ll long long 
int dpmax[maxn][20],a[maxn],n;
ll k;
void ST(){
    memset(dpmax,0,sizeof dpmax);
    for(int i=1;i<=n;i++) dpmax[i][0]=a[i];
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
            dpmax[i][j]=max(dpmax[i][j-1],dpmax[i+(1<<(j-1))][j-1]);
}
int query(int L,int R){
    int k=log2(R-L+1);
    return max(dpmax[L][k],dpmax[R-(1<<k)+1][k]);
}
int judge(int m){//分成m组是否可行
    ll tot=0;
    int len=n/m,cur=1;//每组len人
    for(int i=1;i<=m;i++)
        tot+=query((i-1)*len+1,i*len);
    if(tot>k) return 1;
    return 0;
}
int main(){
    while(scanf("%d%lld",&n,&k) && n>0){
        for(int i=1;i<=n;i++) 
            scanf("%d",&a[i]);
        ST();
        int l=1,r=n,ans=-1;
        while(l<=r){
            int mid=l+r>>1;
            if(judge(mid)) 
                ans=mid,r=mid-1;
            else l=mid+1;
        }
        printf("%d\n",ans);
    }
}

 

posted on 2018-11-28 16:35  zsben  阅读(125)  评论(0编辑  收藏  举报

导航