找了半天都没找到太简单的==这个题面试n个人,可以分任意组数,每组选一个,得分总和严格大于k,问最少分几组

一说最大最小的不看分类也知道是rmq,其实自己是想到用二分的,可是你为什么不自己试着写写呢??比赛的时候又不能确定思路再写,自己都WA多少遍还不知道思路对不对呢,这样不行啊。。。还有,标准二分的写法是不是得熟练一些啊。再有就是,这么大的数据量,多余的数组就彻底删了啊,MLE多少次不长记性==

/************
hdu3486
2016.1.19
748MS 18180K 1813 B C++
************/
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXN 200010
int  mx[MAXN][20], w[MAXN];
int n, k;
void rmqinit()
{
    for(int i = 1; i <= n; i++)  mx[i][0] = w[i];
    int m = (int)(log(n * 1.0) / log(2.0));
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= n; j++)
        {
            mx[j][i] = mx[j][i - 1];
            if(j + (1 << (i - 1)) <= n) mx[j][i] = max(mx[j][i], mx[j + (1 << (i - 1))][i - 1]);
        }
}
int rmqmax(int l,int r)
{
    int m = (int)(log((r - l + 1) * 1.0) / log(2.0));
    return max(mx[l][m] , mx[r - (1 << m) + 1][m]);
}
int fun(int x,int y)//len num
{
    int ans=0;
    for(int i=1;i<=y;i++)
    {
        ans+=rmqmax((i-1)*x+1,i*x);
        if(ans>k) return ans;
    }
    return ans;
}
int main()
{
   // freopen("cin.txt","r",stdin);
    while(~scanf("%d%d",&n,&k))
    {
        if(n==-1&&k==-1) break;
        int sum=0,l,r,mid,ans=0;
        bool flag=0;
        for(int i=1;i<=n;i++) {
            scanf("%d",&w[i]);
            sum+=w[i];
            if(w[i]>=k)
            {

                flag=1;
            }
        }
        if(flag) {printf("1\n");continue;}
        if(sum<=k)
        {
            printf("-1\n");
            continue;
        }
        rmqinit();
        l=1,r=n;
        while(l<=r)
        {
            mid=(l+r)/2;
          //  printf("l=%d,r=%d,mid=%d.",l,r,mid);
            int t=fun(n/mid,mid);//mid是每组个数
           // printf("t=%d\n",t);
            if(t>k)
            {
                r=mid-1;
                ans=mid;
            }
            else l=mid+1;
        }
        printf("%d\n",ans);
    }
    return 0;
}
int mi[MAXN][17], mx[MAXN][17], w[MAXN];
int n, q;
void rmqinit()
{
    for(int i = 1; i <= n; i++) mi[i][0] = mx[i][0] = w[i];
    int m = (int)(log(n * 1.0) / log(2.0));
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= n; j++)
        {
            mx[j][i] = mx[j][i - 1];
            if(j + (1 << (i - 1)) <= n) mx[j][i] = max(mx[j][i], mx[j + (1 << (i - 1))][i - 1]);
            mi[j][i] = mi[j][i - 1];
            if(j + (1 << (i - 1)) <= n) mi[j][i] = min(mi[j][i], mi[j + (1 << (i - 1))][i - 1]);
        }
}
int rmqmin(int l,int r)
{
    int m = (int)(log((r - l + 1) * 1.0) / log(2.0));
    return min(mi[l][m] , mi[r - (1 << m) + 1][m]);
}
int rmqmax(int l,int r)
{
    int m = (int)(log((r - l + 1) * 1.0) / log(2.0));
    return max(mx[l][m] , mx[r - (1 << m) + 1][m]);
}

返回下标:

int mi[MAXN][17], mx[MAXN][17], w[MAXN];
int n, q;
void rmqinit()
{
    for(int i = 1; i <= n; i++) mi[i][0] = mx[i][0] = i;
    int m = (int)(log(n * 1.0) / log(2.0));
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= n; j++)
        {
            mx[j][i] = mx[j][i - 1];
            mi[j][i] = mi[j][i - 1];
            if(j + (1 << (i - 1)) <= n)
            {
                if(w[mx[j][i]] < w[mx[j + (1 << (i - 1))][i - 1]]) mx[j][i] = mx[j + (1 << (i - 1))][i - 1];
                if(w[mi[j][i]] > w[mi[j + (1 << (i - 1))][i - 1]]) mi[j][i] = mi[j + (1 << (i - 1))][i - 1];
            }
        }
}
int rmqmin(int l,int r)
{
    int m = (int)(log((r - l + 1) * 1.0) / log(2.0));
    if(w[mi[l][m]] > w[mi[r - (1 << m) + 1][m]]) return mi[r - (1 << m) + 1][m];
    else return mi[l][m];
}
int rmqmax(int l,int r)
{
    int m = (int)(log((r - l + 1) * 1.0) / log(2.0));
    if(w[mx[l][m]] < w[mx[r - (1 << m) + 1][m]]) return mx[r - (1 << m) + 1][m];
    else return mx[l][m];
}