题目大意是找最小的m使得前m段中每一段的最大值相加严格大于k,每一段长度为[n/m](n/m向下取整,多余的后半部分部分n-m*[n/m]不要)

先给一段我一开始的思路,和网上许多题解思路一样,但其实是有错误的。二分答案+RMQ (RMQ部分也可以用线段树)

#include <bits/stdc++.h>
using namespace std; const int maxn = 2e5 + ;
const int inf = 0x3f3f3f3f;
int f[maxn][];
int n, k, m, v[maxn];
int mx, mi, tot;
inline int max( int a,int b ){
return a>b ? a:b;
} inline int min( int a, int b ){
return a<b ? a:b;
} inline void ST_make(){
for( int i=; i<=n; i++ )
f[i][] = v[i];
for( int j=; (<<j)<=n; j++ )
for( int i=; i<=n; i++ )
f[i][j] = max( f[i][j-], f[i+(<<(j-))][j-] );
} inline int ST_query( int l, int r ){
int k = log(r-l+)/log();
return max( f[l][k], f[r-(<<k)+][k]);
} int main(){
while( ~scanf("%d%d", &n, &k) ){
if( n< && k< ) break;
memset( f, , sizeof(f) );
mx = -inf; mi = inf;
tot = ;
for( int i=; i<=n; i++ ){
scanf("%d", &v[i]);
tot += v[i];
mx = max( v[i], mx );
mi = min( v[i], mi );
}
if( mx>k ) {puts("1\n"); continue;}
else if( tot<=k ) {puts("-1\n"); continue;}
ST_make();
mx = mx ? mx:;
mi = mi ? mi:;
int l = k/mx, r = min( n, k/mi+ ), sum; //判断上下界,节省时间
while( l<r ){
sum = ;
int mid = l+r>>; //这个地方不能直接用m = l+r>>1
int t = n/mid;
int tmp = ;
int d = t*mid;
while( tmp<d){
sum += ST_query( tmp, tmp+t- );
tmp += t;
}
if( sum>k ){ //符合条件再令m = mid;
r = mid;
m = mid;
}
else l = mid+;
}
printf("%d\n", m);
} return ;
}

思路都写好了,然鹅是错的。。。

给一份Discuss里dalao给的卡二分的数据

10 1500
1 1 1 1 1000 1000 1 1 1 1
很明显 答案是2 但是输出我记得好像是7
所以换了暴力枚举的思路,上代码
#include <bits/stdc++.h>
using namespace std; const int maxn = 2e5 + ;
const int inf = 0x3f3f3f3f;
int f[maxn][];
int n, k, m, v[maxn];
int mx, mi, tot;
inline int max( int a,int b ){
return a>b ? a:b;
} inline int min( int a, int b ){
return a<b ? a:b;
} inline void ST_make(){
for( int i=; i<=n; i++ )
f[i][] = v[i];
int t = log(n)/log()+;
for( int j=; j<t; j++ )
for( int i=; i+(<<j)-<=n; i++ )
f[i][j] = max( f[i][j-], f[i+(<<(j-))][j-] );
} inline int ST_query( int l, int r ){
int k = log(r-l+)/log();
return max( f[l][k], f[r-(<<k)+][k]);
} int main(){
while( ~scanf("%d%d", &n, &k) ){
if( n< && k< ) break;
mx = -inf; mi = inf;
tot = ;
for( int i=; i<=n; i++ ){
scanf("%d", &v[i]);
tot += v[i];
mx = max( v[i], mx );
mi = min( v[i], mi );
}
if( tot<=k ){
printf("-1\n");
continue ;
}
ST_make();
mx = mx ? mx:;
mi = mi ? mi:;
int l = k/mx, r = (k/mi+, n); //判定上下界,节省时间(好像判了上界r还慢了。。)
if(l==) l = ;               
bool ok = ;
for( m=l; m<=r; m++ ){
int sum = ;
int t = n/m;
int d = t*m;
for( int i=; i<=d; i+=t ) //这个地方要等于号,可举例n = m时 若i<d为判定条件则不能进行,卡了一年
sum += ST_query( i, i+t- );
if( sum>k ){
ok = ;
break;
}
}
if(ok) printf("%d\n", m);
else printf("-1\n");
}
return ;
}

hdu3486Interviewe(二分是错的)(ST算法RMQ + 判定上下界枚举)的更多相关文章

  1. 【37.48%】【hdu 2587】How far away ?(3篇文章,3种做法,LCA之ST算法(RMQ))

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  2. 【原创】RMQ - ST算法详解

    ST算法: ID数组下标: 1   2   3   4   5   6   7   8   9    ID数组元素: 5   7   3   1   4   8   2   9   8 1.ST算法作 ...

  3. RMQ问题之ST算法

    RMQ问题之ST算法 RMQ(Range Minimum/Maximum Query)问题,即区间最值问题.给你n个数,a1 , a2 , a3 , ... ,an,求出区间 [ l , r ]的最大 ...

  4. HDU 5289 Assignment (ST算法区间最值+二分)

    题目链接:pid=5289">http://acm.hdu.edu.cn/showproblem.php?pid=5289 题面: Assignment Time Limit: 400 ...

  5. HDU 5443 The Water Problem (ST算法)

    题目链接:HDU 5443 Problem Description In Land waterless, water is a very limited resource. People always ...

  6. CodeForces 359D (数论+二分+ST算法)

    题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=47319 题目大意:给定一个序列,要求确定一个子序列,①使得该子序 ...

  7. 求解区间最值 - RMQ - ST 算法介绍

    解析 ST 算法是 RMQ(Range Minimum/Maximum Query)中一个很经典的算法,它天生用来求得一个区间的最值,但却不能维护最值,也就是说,过程中不能改变区间中的某个元素的值.O ...

  8. RMQ之ST算法模板

    #include<stdio.h> #include<string.h> #include<iostream> using namespace std; ; ],M ...

  9. RMQ问题(线段树+ST算法)

    转载自:http://kmplayer.iteye.com/blog/575725 RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ ...

随机推荐

  1. ssh_exchange_identification: read: Connection reset by peer 解决思路

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/Jdk_yxs/article/deta ...

  2. mysql 5.7开启sql日志的配置

    今天把数据库换成了5.7的,想查通过sql日志定位下问题,但是发现和以前的方式不一样了,特意记录下来 通过开启mysql的日志功能,可以记录所有别执行过的sql语句记录,便于维护数据库数据. 在数据库 ...

  3. .NET Core 之 Nancy 基本使用

    Nancy简介 Nancy是一个轻量级的独立的框架,下面是官网的一些介绍: Nancy 是一个轻量级用于构建基于 HTTP 的 Web 服务,基于 .NET 和 Mono 平台,框架的目标是保持尽可能 ...

  4. Nginx为什么可以支持高并发

    Nginx是由一个俄罗斯人专门为解决高并发而开发的 nginx 采用的是多进程+epoll,能实现高并发,其可以支持的并发上限大概是同时支持5W个连接 1 多进程 nginx 在启动后,会有一个 ma ...

  5. [转帖]Stack Overflow上188万浏览量的提问:Java 到底是值传递还是引用传递?

    Stack Overflow上188万浏览量的提问:Java 到底是值传递还是引用传递? http://www.itpub.net/2019/12/03/4567/   在逛 Stack Overfl ...

  6. Versioning information could not be retrieved from the NuGet package repository. Please try again later.

    Versioning information could not be retrieved from the NuGet package repository. Please try again la ...

  7. Kubernetes集群中Jmeter对公司演示的压力测试

    6分钟阅读 背景 压力测试是评估Web应用程序性能的有效方法.此外,越来越多的Web应用程序被分解为几个微服务,每个微服务的性能可能会有所不同,因为有些是计算密集型的,而有些是IO密集型的. 基于微服 ...

  8. C复习 (C premier plus和C和指针)

  9. 深度学习-强化学习(RL)概述笔记

    强化学习(Reinforcement Learning)简介 强化学习是机器学习中的一个领域,强调如何基于环境而行动,以取得最大化的预期利益.其灵感来源于心理学中的行为主义理论,即有机体如何在环境给予 ...

  10. android studio下 library打包文件(.aar)和本地引用

    关键点: 利用Gradle发布本地maven库支持android library 打包文件(*.aar) 的本地引用 开发环境: windows7 64位操作系统 android studio0.5. ...