hdu 3486 RMQ + 二分
#include<stdio.h>
#include<string.h>
const int MAX = 200010;
#define min(a,b) a<b?a:b
#define max(a,b) a>b?a:b
int dp[MAX][30],a[MAX];
int k;
void init(int n)
{
memset(dp,0,sizeof(dp));
int i,j,m;
for(i=1;i<=n;i++)
{
dp[i][0]=a[i];
}
for(j=1,m=1;m<=n;m<<=1,j++)
for(i=n;i>=1;i--)
{
if(i+(1<<(j-1))<=n)
dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
}
int RMQ(int l,int r)
{
int i,j,k,a;
k=r-l+1;
for(i=0,j=1;j<=k;j<<=1,i++)
{
a=max(dp[l][i],dp[r-j+1][i]);
}
return a;
}
int getmax(int per,int mid)
{
int i;
int ans=0;
for(i=1;i<=mid;i++)
{
ans+=RMQ((i-1)*per+1,i*per);
if(ans>k) return ans;
}
return 0;
}
int main()
{
int n,i;
while(scanf("%d%d",&n,&k),n>0)
{
int sum=0;
int num=0;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]>num) num=a[i];
sum+=a[i];
}
if(num>k){ printf("1\n");continue;}
if(sum<=k)
{printf("-1\n");continue;}
init(n);
// printf("%d %d\n",RMQ(1,3),RMQ(9,8));check RMQ
int l=1,r=n,mid;
int ans=0;
while(l<=r)
{
mid=(l+r)>>1;
int per=n/mid;
int tmp=getmax(per,mid);
if(tmp>k)
{
r=mid-1;
ans=mid;
}
else l=mid+1;
}
printf("%d\n",ans);
}
return 0;
}
RMQ写法换了,93ms!!!
#include<string.h>
#include<stdio.h>
#include<math.h>
const int MAX=200005;
int max(int a,int b){return a>b?a:b;}
int dp[MAX][20],a[MAX];
int n,k,val[MAX];
int LOG[MAX];
void Make_Rmq(int n,int b[])
{
int i,j;
for(i=1;i<=n;i++)
dp[0][i]=b[i];
for(i=1;i<=LOG[n];i++)
{
int limit=n+1-(1<<i);
for(j=1;j<=limit;j++)
dp[i][j]=max(dp[i-1][j],dp[i-1][j+(1<<i>>1)]);
}
}
int RMQ(int l,int r)
{
int k=LOG[r-l+1];
return max(dp[k][l],dp[k][r-(1<<k)+1]);
}
int getmax(int per,int mid)
{
int i;
int ans=0;
for(i=1;i<=mid;i++)
{
ans+=RMQ((i-1)*per+1,i*per);
if(ans>k) return ans;
}
return 0;
}
int get_val()
{
int ret(0);
char c;
while((c=getchar())==' '||c=='\n'||c=='\r');
ret=c-'0';
while((c=getchar())!=' '&&c!='\n'&&c!='\r')
ret=ret*10+c-'0';
return ret;
}
int main()
{
int i;
LOG[0]=-1;
for(i=1;i<MAX;i++)
LOG[i]=LOG[i>>1]+1;
while(scanf("%d%d",&n,&k),n>0)
{
int sum=0;
int num=0;
for(i=1;i<=n;i++)
{
// scanf("%d",&val[i]);
val[i]=get_val();
if(val[i]>num) num=val[i];
sum+=val[i];
}
if(num>k){ printf("1\n");continue;}
if(sum<=k)
{printf("-1\n");continue;}
Make_Rmq(n,val);
int l=1,r=n,mid;
int ans=0;
while(l<=r)
{
mid=(l+r)>>1;
int per=n/mid;
int tmp=getmax(per,mid);
if(tmp>k)
{
r=mid-1;
ans=mid;
}
else l=mid+1;
}
printf("%d\n",ans);
}
return 0;
}

浙公网安备 33010602011771号