首页 > 其他分享 >单调栈和单调队列

单调栈和单调队列

时间:2024-07-27 10:50:19浏览次数:5  
标签:const 队列 top stk int && ans 单调

单调栈和单调队列

P5788

#include <bits/stdc++.h>
using namespace std;
const int N=3e6+5;
int n,a[N],ans[N],top,stk[N];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		while(top>0 && a[stk[top]]<a[i]){
			ans[stk[top--]]=i;
		}
		stk[++top]=i;
	}
	for(int i=1;i<=n;++i){
		printf("%d ",ans[i]);
	}
	return 0;
}

B3666

#include <bits/stdc++.h>
#define LL unsigned long long
using namespace std;
const int N=1e6+5;
int n,top,stk[N];
LL a[N],ans;
int main(){
	//留在栈中的是后缀最大值
	//利用(a^b)^b=a消除影响
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%llu",&a[i]);
		while(top && a[stk[top]]<=a[i]){
			ans^=stk[top--];
		}
		ans^=i;
		stk[++top]=i;
		printf("%llu\n",ans);
	}
	return 0;
}

P2947

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N],stk[N],ans[N],top;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		while(top && a[stk[top]]<a[i]){
			ans[stk[top--]]=i;
		}
		stk[++top]=i;
	}
	for(int i=1;i<=n;++i){
		printf("%d\n",ans[i]);
	}
	return 0;
}

P6510

/*
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,maxx[N][25],ans;
int query(int L,int R){
	int t=log2(R-L+1);
	return max(maxx[L][t],maxx[R-(1<<t)+1][t]);
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&maxx[i][0]);
	}
	for(int j=1;j<=20;++j){
		for(int i=1;i+(1<<j)-1<=n;++i){
			maxx[i][j]=max(maxx[i][j-1],maxx[i+(1<<(j-1))][j-1]);
		}
	}
	// printf("%d\n",query(1,2));
	int R=1;
	for(int L=1;L<=n;++L){
		if(L>R) R=L;
		// printf("%d %d\n",L,R);
		while(R<n && maxx[R+1][0]>maxx[L][0]){
			R++;
			if(maxx[R][0]>query(L,R-1) && L!=R){
				ans=max(ans,R-L+1);
			}
		}
		if(L<R && maxx[R][0]>query(L,R-1)){
			ans=max(ans,R-L+1);
		}
	}
	printf("%d",ans);
	return 0;
}
*/
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N],stkmax[N],stkmin[N],topmax,topmin,ans;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		while(topmax && a[stkmax[topmax]]<a[i]) topmax--;
		while(topmin && a[stkmin[topmin]]>=a[i]) topmin--;//等于的值无法作为有端点
		int k=upper_bound(stkmin+1,stkmin+1+topmin,stkmax[topmax])-stkmin;
		if(k!=topmin+1) ans=max(ans,i-stkmin[k]+1);
		stkmax[++topmax]=i;
		stkmin[++topmin]=i;
	}
	//枚举右端点i,左端点一定是1~i的后缀最小值中大于1~i-1的后缀最大值的值
	printf("%d",ans);
	return 0;
}

P6503

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=3e5+5;
int n,top,stk[N],prex[N],sufx[N],pren[N],sufn[N];
LL a[N],ans;
void clear(){
	top=0;
	memset(stk,0,sizeof(stk));
}
int main(){
	scanf("%d",&n);
	//小细节:一边带“=”一边不带“=”是为去重
	for(int i=1;i<=n;++i){
		sufx[i]=sufn[i]=n+1;
	}
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		while(top && a[stk[top]]<=a[i]){
			sufx[stk[top--]]=i;
		}
		stk[++top]=i;
	}
	clear();
	for(int i=n;i>=1;--i){
		while(top && a[stk[top]]<a[i]){
			prex[stk[top--]]=i;
		}
		stk[++top]=i;
		// printf("%d\n",stk[top]);
	}
	clear();
	for(int i=1;i<=n;++i){
		while(top && a[stk[top]]>=a[i]){
			sufn[stk[top--]]=i;
		}
		stk[++top]=i;
	}
	clear();
	for(int i=n;i>=1;--i){
		while(top && a[stk[top]]>a[i]){
			pren[stk[top--]]=i;
		}
		stk[++top]=i;
	}
	for(int i=1;i<=n;++i){
		// printf("%d %d\n",prex[i],sufx[i]);
		ans+=a[i]*(sufx[i]-i)*(i-prex[i]);
		ans-=a[i]*(sufn[i]-i)*(i-pren[i]);
		// printf("%lld\n",ans);
	}
	printf("%lld",ans);
	return 0;
}

P1886

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,k,a[N],q[N],L,R,ans1[N],ans2[N];
int main(){
	scanf("%d %d",&n,&k);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
	}
	L=1;
	for(int i=1;i<=k;++i){
		while(R>=L && a[q[R]]<=a[i]) R--;
		q[++R]=i;
	}
	ans1[k]=a[q[L]];
	for(int i=k+1;i<=n;++i){
		if(i-k==q[L]) L++;
		while(R>=L && a[q[R]]<=a[i]) R--;
		q[++R]=i;
		ans1[i]=a[q[L]];
	}
	memset(q,0,sizeof(q));
	L=1,R=0;
	for(int i=1;i<=k;i++){
		while(R>=L && a[q[R]]>=a[i]) R--;
		q[++R]=i;
	}
	ans2[k]=a[q[L]];
	for(int i=k+1;i<=n;++i){
		if(i-k==q[L]) L++;
		while(R>=L && a[q[R]]>=a[i]) R--;
		q[++R]=i;
		ans2[i]=a[q[L]];
	}
	for(int i=k;i<=n;++i){
		printf("%d ",ans2[i]);
	}
	puts("");
	for(int i=k;i<=n;++i){
		printf("%d ",ans1[i]);
	}
	return 0;
}

标签:const,队列,top,stk,int,&&,ans,单调
From: https://www.cnblogs.com/mj666/p/18326718

相关文章

  • 直播平台搭建,需要实现的核心要素之队列
    直播平台搭建,需要实现的核心要素之队列队列的实现在直播平台搭建中,队列的实现分为队列的定义和操作,如前所述,队列是元素的有序集合,添加操作发生在其尾部,移除操作则发生在头部。队列的操作顺序是先进先出(FIFO),它支持以下操作。Queue():创建一个空队列。它不需要参数,且会......
  • DAY10 栈与队列part01
     理论基础文章讲解:https://programmercarl.com/%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html232.用栈实现队列 注意为什么要用两个栈题目链接/文章讲解/视频讲解:https://programmercarl.com/0232.%E7%94%A8%E6%A0%88%E5%AE%9E%E7%8E%......
  • C++优先队列 涵盖各种易错,技巧,应用和原理(附手写代码)
    当然也可以不看==> 阅读我的文章前请务必先阅读此文章! 都是废话这个文章里有视频,不知道为什么一点开文章就会播放,可以先翻到最后暂停一下再回来看目录阅读文章须知引言优先队列的概念优先队列的创建优先队列的操作*还有一些不常用的:优先队列的技巧如果类型是结构......
  • 软考-软件设计师(3)-数据结构与算法:树、图、队列、查找算法、排序算法、霍夫曼编码/
    场景软考-软件设计师-数据结构与算法模块高频考点整理。以下为高频考点、知识点汇总,不代表该模块所有知识点覆盖,请以官方教程提纲为准。注:博客:霸道流氓气质-CSDN博客实现知识点树:节点的度、树的度、深度、高度、满二叉树、完全二叉树、平衡二叉树、B树、二叉排序树节点......
  • 代码随想录day10 || 232 栈实现队列, 225 队列实现栈,20 删除有效括号,1047 删除字符串相
    232实现队列//go本身并不支持原生的栈和队列结构,都是通过切片实现的//leetcodesubmitregionbegin(Prohibitmodificationanddeletion)typeMyQueuestruct{ Data[]int Sizeint}funcConstructor()MyQueue{ returnMyQueue{}}func(this*MyQueue)Push(......
  • Day10 栈和队列Part1
    任务232.用栈实现队列请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty)思路算是一个模拟类的题目,用py中,用列表加上限制条件表示栈(只能用pop表示对栈顶元素出栈处理)push:用stackIn保存入队元素pop:出队时,分三种情况,如果队列......
  • 算法入门篇(四)之栈和队列
    目录一、顺序栈、链栈1、顺序栈1.定义与存储结构2.特点3.适用场景2、链栈1.定义与存储结构2.特点3.适用场景3、总结二、顺序队列、链式队列1、顺序队列1.定义与存储结构2.特点3.循环队列4.适用场景2、链式队列1.定义与存储结构2.特点3.适用......
  • 数据结构之队列详解
    1.队列的概念以及结构队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFo(FristinFristout)的特性入队列:进行插入才操作的一端称为队尾出队列:进行删除操作的一端称为队头2.队列的实现队列也可以使用数组和链表的结构实现,使用......
  • 栈,队列,链表
     栈堆栈又名栈(stack),它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈......
  • 通过“ 栈 ”实现“ 队列 ”
                  ......