首页 > 其他分享 >洛谷P10878 [JRKSJ R9] 在相思树下 III && 单调队列

洛谷P10878 [JRKSJ R9] 在相思树下 III && 单调队列

时间:2024-08-23 16:16:02浏览次数:13  
标签:P10878 洛谷 1000100 int R9 long 队列 maxn 单调

传送门:P10878 [JRKSJ R9] 在相思树下 III

将军啊,早卸甲,他还在廿二,等你回家……

一道练习单调队列的好题 qwq

题目意思:

很明白了,不再复述。(注意 $ \forall i$ 表示对于任意的 i ,可理解为所有)

思路:

贪心是很明显的,因为我们要让最后的值最大,首先要把小的值删掉。
最后的答案就是进行 m 次操作 1 后的序列中的最小值。
考虑怎样求操作后的序列:

暴力:

枚举 + 判断 绝对TLE

正解

我们发现,操作后的序列中,第 \(i\) 项的值就是原序列中第 \(i\) 项到第 \(i+m\) 项中的最大值。好像可以用二分吗?
那么我们要做的就是查询每一个 \(i\) 到第 \(i+m\) 的最大值。

  • 蒟蒻首先想到的是线段树。。我承认是线段树水题做多了
    维护线段树的区间最大值,枚举 \(i\) 从 \(1\) 到 \(n-m\) ,每次求 \(i\) 到 \(i+m\) 的最大值,再对所有最大值取最小。。(代码会在后面给)
  • 但是还有更好的做法:单调队列,又称滑动窗口。放一道练手题:P1886 滑动窗口 /【模板】单调队列
    详解请往后翻 qwq
    这样就是个板子了。。。

详解 · 单调队列

队伍内元素保持单调性,保持的方法就是挤掉队尾不能保持单调性的元素。
可以通过双端队列 deque 来实现。
但是 zhx 曾曰过:STL 太慢了
所以给出一份手写的代码:

#include<bits/stdc++.h>

using namespace std;

int n,m;
int a[1001000];
int q[1000100];
int ans1[1000100];
int ans2[1000100];

int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i]; 
	}
	int head=1,tail=0;
	for(int i=1;i<=n;i++)//单调上升
	{
		while(a[i]<a[q[tail]]&&head<=tail)tail--;
		q[++tail]=i;
		while(head<=tail&&q[head]<=i-m) head++;
		if(i>=m)cout<<a[q[head]]<<" ";
	}
	cout<<endl;
	memset(q,0,sizeof(q));
	head=1;tail=0;
	for(int i=1;i<=n;i++)//单调下降
	{
		while(a[i]>a[q[tail]]&&head<=tail)tail--;
		q[++tail]=i;
		while(head<=tail&&q[head]<=i-m) head++;
		if(i>=m)cout<<a[q[head]]<<" ";
	}
	return 0;
}

最终代码:

线段树:只需要有区间查询功能就可以了

#include<bits/stdc++.h>

using namespace std;

#define int long long //不开 long long 见祖宗

int m,n;
int a[1000100];
int minn=LLONG_MAX; //这个地方要用 long long 范围下的最大值,要不然会 WA 掉 1、2、4

struct node{
	int l,r;
	int maxn;
}z[4000100];

node operator+(const node &l,const node &r)
{
	node res;
	res.l=l.l,res.r=r.r;
	res.maxn=max(l.maxn,r.maxn);
	return res;
}

void build(int l,int r,int rt)
{
	if(l==r)
	{
		z[rt].l=z[rt].r=l;
		z[rt].maxn=a[l];
		return;
	}
	int mid=l+r>>1;
	build(l,mid,rt<<1);
	build(mid+1,r,rt<<1|1);
	z[rt]=z[rt<<1]+z[rt<<1|1];
}

int query(int l,int r,int rt,int nowl,int nowr)
{
	if(nowl<=l&&nowr>=r){
		return z[rt].maxn;
	}
	int mid=l+r>>1;
	if (nowl<=mid)
	{
		if (mid<nowr)
			return max(query(l,mid,rt<<1,nowl,nowr),query(mid+1,r,rt<<1|1,nowl,nowr));//这个地方依旧是我的重灾区 qwq
		else
			return query(l,mid,rt<<1,nowl,nowr); 
	}
	else
		return query(mid+1,r,rt<<1|1,nowl,nowr); 
}

signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	build(1,n,1);
	for(int i=1;i<=n-m;i++)
	{
		int p=query(1,n,1,i,i+m);
		minn=min(minn,p);
	}
	cout<<minn<<endl;
	return 0;
}

单调队列:跟线段树对比来看码量好少

#include<bits/stdc++.h>

using namespace std;

#define int long long

int n,m;
int a[1000100];
int q[1000100];
int ans=LLONG_MAX;

signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	int head=1,tail=0;
	m+=1;
	for(int i=1;i<=n;i++)//单调下降的序列,求最大值 
	{
		while(a[i]>a[q[tail]]&&head<=tail)tail--;
		q[++tail]=i;
		while(head<=tail&&q[head]<=i-m) head++;
		if(i>=m)ans=min(ans,a[q[head]]);
	}
	cout<<ans<<endl;
 } 

标签:P10878,洛谷,1000100,int,R9,long,队列,maxn,单调
From: https://www.cnblogs.com/lazy-ZJY0307/p/18376310

相关文章

  • 洛谷P1182 数列分段 Section II
    传送门:P1182数列分段SectionII消灭人类暴政,世界属于三体题目意思:题目说的很明白了思路:考虑部分分:20%的数据保证n<10,直接爆搜;40%的数据保证n<1000,n^2+前缀和搞定100%的数据:求每段最大和的最小值:明显的二分(n在10^5的范围也说明了这一点,因为二分查找的......
  • 洛谷P1540 [NOIP2010 提高组] 机器翻译答案
    #include<bits/stdc++.h>usingnamespacestd;/*数据结构:队列queue 桶:标记某个单词是否出现在内存中 t[i]=false:不在t[i]=true:在对于读入的每个单词x: 如果不存在单词x 存储(入队) t[x]=true 内存中元素个数(q.size())>M: t[q.front()]=falses; ......
  • 洛谷 P2590 [ZJOI2008] 树的统计 题解
    题目大意给你一个\(N\),然后再给你两个长度为\(N\)的序列。让你构造一个仅有\(0\)和\(1\)的\(N\timesN\)的正方形,但是要满足两个序列的顺序:第一个序列指的是该正方形每一行所构成的二进制数的大小顺序。第二个序列指的是该正方形每一列所构成的二进制数的大小顺序。......
  • 洛谷P3528 [POI2011] PAT-Sticks && 数据结构之堆
    传送门:P3528[POI2011]PAT-Sticks与买桂花同载酒,终不似,少年游这是现在为止洛谷上的最优解!!翻译题目描述小约翰尼的爷爷奶奶送给他一份生日礼物。这份礼物是一盒长度和颜色各异的木棍。约翰尼想知道,在他得到的这组木棍中,是否存在三根木棍能够组成一个三边颜色各不相同的三......
  • Effective-Java-Chapter9-通用程序设计
    https://github.com/clxering/Effective-Java-3rd-edition-Chinese-English-bilingual/blob/dev/Chapter-9/Chapter-9-Introduction.md准则一将局部变量的作用域最小化不要在变量使用之前就申明,在需要使用的时候进行申明。当然这条准则不是那么绝对,大部分时候遵守就好。......
  • 【LGR-196-Div.4】洛谷入门赛 #26 题A - H 详细题解--优化思路简洁代码(C++,Python语
    前言:    觉得这个比赛很有意思的,都是暴力题,涉及一些细节,难度比较适合刚学编程语言的,可以很好的锻炼基础还有手速,最后两题也是比较有意思,之后也准备更新atc的比赛题解和洛谷的一些高质量比赛题解(算法网瘾就是想参加各种比赛)   如果觉得有帮助,或者觉得我写的好,......
  • 洛谷 P5731 蛇形方阵
    目录题目-蛇形方阵题目描述输入格式输出格式样例样例输入#1样例输出#1提示ACCODE思路ACCODE题目-蛇形方阵题目描述给出一个不大于9的正整数n,输出n×n的蛇形方阵。从左上角填上1开始,顺时针方向依次填入数字,如同样例所示。注意每个数字有都会占用3个字符,前面......
  • 洛谷 P1540 [NOIP2010 提高组] 机器翻译
    题目概括给定N个整数,和一个容量为M的“字典”,从头到尾依次翻译,每次翻译先看自家字典,没有的话再看别人的字典并存到自家字典,如果自家字典满了,当前单词的翻译会代替最早进入的。做题思路定义一个长度为M的字典数组,依次遍历N个数,每次翻译先检索字典数组,没有的话加入字典并......
  • 洛谷 P5461 赦免战俘
    赦免战俘题目背景借助反作弊系统,一些在月赛有抄袭作弊行为的选手被抓出来了!题目描述现有2n×2......
  • 洛谷 P3919 可持久化线段树 1 之主席树模板(初级)
    洛谷P3919题解传送锚点摸鱼环节【模板】可持久化线段树1(可持久化数组)题目背景UPDATE:最后一个点时间空间已经放大2021.9.18增添一组hack数据by@panyf标题即题意有了可持久化数组,便可以实现很多衍生的可持久化功能(例如:可持久化并查集)题目描述如题,你需要维护这......