首页 > 其他分享 >[洛谷P3503][POI2010][BZOI2086]Blocks

[洛谷P3503][POI2010][BZOI2086]Blocks

时间:2024-02-22 10:24:05浏览次数:32  
标签:ll Blocks int sum tp long BZOI2086 P3503 top

image
先看数据范围,n ≤ 1e7,k ≤ 1e9,暴力显然行不通,只能考虑单调栈;
首先题目中说每一个数都要大于 k ,那么我们可以在初始化时就将每一个数都减去 k ,将问题转化为从正数中取出数加到负数里
然后维护一个前缀和,来判断一个区间是否符合要求;显然,当sum[j]-sum[i] ≥ 0时,区间[i+1,j]符合题意,长度为 j-i;
所以,到这一步,其实上是求出 满足 sum[j]-sum[i] ≥ 0 时 j-i 的最大值。

初始化
s.clear();//将栈清空,我用的是手写栈,STL栈可以使用 while(!s.empty())s.pop() 的方式实现
scanf("%lld",&k);
for(int i=1;i<=n;i++){
	sum[i]=sum[i-1]+a[i]-k;
}

接下来,考虑实现方式;
我们发现,如果 i ≤ j && sum[i] ≤ sum[j] , 那么明显以 i 作为区间的左端点比 j 更优;
所以维护单调栈时,只有 sum[i] ≤ sum[s.top()] 时才能够将其压入栈中,所以这是一个单调递减栈;
因为我们是从1~n找出的单调栈,而我们要寻找最大区间,所以在寻找最左边界时,要从n倒着遍历;
当当前元素的前缀和大于等于栈顶元素的前缀和,即 sum[i] ≥ sum[s.top()] 时,就得到了一组合法解,然后将其pop掉;
而当 sum[i] < sum[s.top()] 时,由于栈中元素是单调递减的,当前解不合法,栈中其它的解也就更不合法了,不用再去考虑;
最后更新ans值即可。
另外:要开long long,因为有前缀和

完整代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e7+5;
const int inf=0x7fffffff;
ll n,a[N],tmp[N],sum[N],m,k,maxn=-inf;//十年OI一场空,不开long long见祖宗
struct Stack{//手写栈,基本操作和STL栈一样,只多一个clear()
	int stk[N];
	int tp;
	void clear(){tp=0;}
	int top(){return stk[tp];}
	void push(int x){stk[++tp]=x;}
	void pop(){tp--;}
	bool empty(){return tp==0;}
	int size(){return tp;}
}s;
int main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	while(m--){
		s.clear();
		scanf("%lld",&k);
		for(int i=1;i<=n;i++){
			sum[i]=sum[i-1]+a[i]-k;//求前缀和,直接减去k
		}
		ll ans=0;
		s.push(0);
		for(int i=1;i<=n;i++)if(sum[s.top()]>=sum[i])s.push(i);//正序搜索,压栈
		for(ll i=n;i>=0;i--){//倒序搜索,寻找合法区间
			ll tmp;
			while(!s.empty()&&sum[s.top()]<=sum[i]){
				tmp=s.top();//区间合法,更新tmp
				s.pop();//栈顶元素退栈
			}
			ans=max(ans,i-tmp);//更新ans的值
		}
		printf("%lld ",ans);
	}
	return 0;
}

标签:ll,Blocks,int,sum,tp,long,BZOI2086,P3503,top
From: https://www.cnblogs.com/LBTL/p/18026734

相关文章

  • Blocks(单调栈)
    题干中说每次选择一个大于k的数,还要选他左右两个数其中之一加上一,最后问你最长的每个数不小于K的子序列。这些都是障眼法,其实就是问你最长的平均值大于或等于K的最长子序列,这样就明朗了。接下来就是找子序列的问题,因为要求的是区间最大平均值,所以不能再以单个数的值为依据来决......
  • blocks——题解
    题目描述解析对于这道题,他要求大于k的数进行操作,所以直接让每个数减k,然后用前缀和维护一下与0比较就可以了,因为一段区间和的平均值大于k的话,那么这就是一个合法区间,即为操作后的这个区间和大于0,我们可以用一个单调递减栈去维护,先把比0小的推入栈中,因为要求最大区间,所以边界......
  • 尝试通过Codeblocks编译Codeblocks
    最近工作安排上的空余时间比较多.尝试了下通过Codeblocks去编译(Self-host)Codeblocks还传了个Gitee(code-blocks-mint),不知道后面会不会继续对其进行修改——主要最近习惯了使用qml这种脚本化的界面实现方式,看见widget跟页面标签就一阵头大;另外,Codeblocks的代码虽然相对屎......
  • 页面中的blockShow组件展示,可进行相关的样式修改,一般月饼图搭配使用,具体根据实际来
    <template><!--这是新版的相对应的颜色列表的UI--><divclass="bllockListShow"><divclass="pieList"v-for="(item,index)indataArr":key="index"@click="clickUptown(index,item)"......
  • KubeBlocks 研发轶事之 addon 抽象
    作者介绍张云杨,前阿里云数据库产品负责人,2016-2019年任阿里云数据库产品总监,负责RDS、PolarDB、Redis、MongoDB等核心产品。目前作者就职于云猿生数据,主要负责云原生数据控制面KubeBlocks和ServerlessMySQL产品。欢迎云计算或数据库行业从业者加微信交流。作者微信:realzyy......
  • 基于 KubeBlocks 的 PikiwiDB(原Pika) 云化下一站
    本文作者:于雨目前任职于360智汇云云平台基础架构部,dubbogo社区负责人,OpenAtomFoundation/pika项目负责人,前蚂蚁集团seata项目负责人。从业⼗四年来⼀直在服务端基础架构工作,热爱开源,陆续参与和改进过Redis/Pika/Muduo/dubbo/dubbo-go/Sentinel-golang/Seata-go等知名项⽬......
  • P2865 [USACO06NOV] Roadblocks G
    原题链接题解1.在处理最短路的时候,我们采用优先队列的方法,即第一个出现的点一定是最小的,之后出现的点都是在其他点的基础上叠加的值,肯定不小于第一个。那么依然是这个思路,第二个出现的点一定是次短的。代码#include<bits/stdc++.h>usingnamespacestd;structunit{in......
  • 【UVA 101】The Blocks Problem 题解(模拟+向量)
    计算机科学的许多领域使用简单、抽象的领域进行分析和实证研究。例如,早期的人工智能规划和机器人研究(STRIPS)使用了一个区块世界,其中机器人arm执行涉及块操作的任务。在这个问题中,您将在某些规则和约束下对一个简单的块世界进行建模。相当地与确定如何达到指定状态相比,您将“编程......
  • uva101The Blocks Problem
    原题链接TheBlocksProblem-洛谷|计算机科学教育新生态(luogu.com.cn)一道模拟题。(水题) 但模拟过程很有意思,怎么样才能用最短的代码完成所有操作,使代码更简洁是很考验技术的。 #include<bits/stdc++.h>usingnamespacestd;vector<int>block[30];vector<int>m;......
  • kubeblocks的使用
    介绍:它是基于Kubernetes的云原生数据基础设施,为用户提供了关系型数据库、NoSQL数据库、向量数据库以及流计算系统的管理控制功能。可以使用提供的命令轻松部署处理数据库实例。github:https://github.com/apecloud/kubeblocks官网:https://kubeblocks.io1.初步使用安装kbcli:......