hdu3486IntervieweRMQ附模板

Posted MissZhou要努力

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu3486IntervieweRMQ附模板相关的知识,希望对你有一定的参考价值。

找了半天都没找到太简单的==这个题面试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];



以上是关于hdu3486IntervieweRMQ附模板的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3486 &amp; HDU 1913 Computers(dp)

Interviewe(hdu3486)

(HDU 1698) Just a Hook(线段树)-附通用模板

悼念512汶川大地震遇难同胞——珍惜现在,感恩生活--hdu2191(多重背包模板)

HDU 3359 高斯消元模板题,

hdu3966(树链剖分+线段树)