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 & HDU 1913 Computers(dp)
(HDU 1698) Just a Hook(线段树)-附通用模板