BZOJ 1342 Baltic2007 Sound静音问题 单调队列

题目大意:给定一个长度为n的序列,求哪些长度为m的区间满足区间内最大值与最小值之差小于等于c

利用单调队列维护区间内的最大值和最小值- - 硬搞就可以了- -

刷刷水题真爽- -

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 1001001
using namespace std;
int n,m,c,a[M];
int q_max[M],r_max,h_max;
int q_min[M],r_min,h_min;
bool flag;
int main()
{
	int i;
	cin>>n>>m>>c;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		{
			int &r=r_max,&h=h_max,*q=q_max;
			while( r-h>=1 && a[q[r]]<a[i] )
				q[r--]=0;
			q[++r]=i;
			while(i-q[h+1]>=m)
				q[++h]=0;
		}
		{
			int &r=r_min,&h=h_min,*q=q_min;
			while( r-h>=1 && a[q[r]]>a[i] )
				q[r--]=0;
			q[++r]=i;
			while(i-q[h+1]>=m)
				q[++h]=0;
		}
		if( i>=m && a[q_max[h_max+1]]-a[q_min[h_min+1]]<=c )
			printf("%d\n",i-m+1),flag=1;
	}
	if(!flag) puts("NONE");
	return 0;
}
时间: 2024-12-24 15:09:31

BZOJ 1342 Baltic2007 Sound静音问题 单调队列的相关文章

1342: [Baltic2007]Sound静音问题

1342: [Baltic2007]Sound静音问题 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 710  Solved: 307[Submit][Status][Discuss] Description 静音问题 数字录音中,声音是用表示空气压力的数字序列描述的,序列中的每个值称为一个采样,每个采样之间间隔一定的时间. 很多声音处理任务都需要将录到的声音分成由静音隔开的几段非静音段.为了避免分成过多或者过少的非静音段,静音通常是这样定义的:m

【BZOJ1342】【Baltic2007】Sound静音问题 单调队列

#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/vmurder/article/details/42971677"); } 题意: 虽然这道题是汉语的,但是我有必要说一下题意. 就是问你长度为m的区间中,有哪些区间的最大值-最小值<=c,输出这个区间的左端点. 注意!!!如果没有方案输出NONE. 题解: 首先我们可以写一个multiset2

[bzoj1342][Baltic2007]Sound静音问题_单调队列

Sound静音问题 bzoj-1342 Baltic-2007 题目大意:给定一个n个数的序列,求所有的长度为m的区间,使得区间内最大值减去最小值不超过阈值c. 注释:$1\le n \le 10^6$,$1\le m\le 10^4$. 想法:单调队列裸题. 定长区间最值问题显然可以用单调队列维护. 最后,附上丑陋的代码... ... #include <iostream> #include <cstdio> #include <cstring> #include &

BZOJ_1342_[Baltic2007]Sound静音问题_单调队列

题意: 给出n个数,求∑[ max{a[i]~a[i+m-1]} - min{a[i]~a[i+m-1]} <= c ] 分析: 滑动窗口 我们维护两个单调队列,分别存最大,最小值 代码: #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define N

BZOJ1342 [Baltic2007]Sound静音问题

越来越水了... 这道题是简单的单调队列,同时维护最大值和最小值即可. 另解:multiset大法求区间最大最小,但是复杂度会上升... 1 /************************************************************** 2 Problem: 1342 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:944 ms 7 Memory:12524 kb 8 ***************

【bzoj 1414】对称的正方形 单调队列+manacher

Description Orez很喜欢搜集一些神秘的数据,并经常把它们排成一个矩阵进行研究.最近,Orez又得到了一些数据,并已经把它们排成了一个n行m列的矩阵.通过观察,Orez发现这些数据蕴涵了一个奇特的数,就是矩阵中上下对称且左右对称的正方形子矩阵的个数. Orez自然很想知道这个数是多少,可是矩阵太大,无法去数.只能请你编个程序来计算出这个数. Input 文件的第一行为两个整数n和m.接下来n行每行包含m个正整数,表示Orez得到的矩阵. Output 文件中仅包含一个整数answer

BZOJ 2806 [Ctsc2012]Cheat ——后缀自动机 单调队列优化DP

先建出广义后缀自动机. 然后跑出文章中每一个位置的最大匹配距离. 然后定义$f[i]$表示匹配到以$i$结尾的串时,最长的匹配距离. 显然可以二分$L$的取值. 然后容易得到$DP$方程 $f[i]=max(f[i-1],f[j]+i-j)(j<=i-L)$ 然后就发现$j$属于一个区间,然后就可以单调队列优化了. #include <map> #include <ctime> #include <cmath> #include <queue> #in

BZOJ 3831 POI 2014 Little Bird 单调队列DP

题目大意:给出一片树林,树排成一排,每一棵树都有一个高度.从地一棵树出发,每次可以跳到i+k棵之前,跳到小于自己高度的树上不需要花费体力,反之需要花费一点体力,问到最后一棵树最少需要多少体力. 思路:简单DP方程:f[i] = min{f[j] + (height[i] >= height[j])} 然后发现数据范围只有O(n)可以过. 维护单调队列,队列中按照f单调递减,队尾按照时间往出弹. 当f值相同的时候,高度较高的优先. CODE: #include <queue> #inclu

BZOJ 3314: [Usaco2013 Nov]Crowded Cows( 单调队列 )

从左到右扫一遍, 维护一个单调不递减队列. 然后再从右往左重复一遍然后就可以统计答案了. ---------------------------------------------------------------------------- #include<bits/stdc++.h> #define rep(i, n) for(int i = 0; i < n; ++i) #define clr(x, c) memset(x, c, sizeof(x)) #define forea