求m区间的最小值

代码1;(手写单调队列)

#include<iostream>
using namespace std;
#define N 2000005
int n,m,a[N],b[N];
int head=0,rear=0;
int main(){
	scanf("%d %d",&n,&m);
	scanf("%d",&a[1]);
	printf("0\n");
	b[rear]=1;
	for(int i=2;i<=n;i++){
		scanf("%d",&a[i]);
		//注意队列为空的判断条件,如果初始化时head=0,rear=1:则当head<rear的时候队列不为空
		//当head==rear=0,则队列head<=rear的时候不为空
		//这里b[head]<i-m而不是小于等于i-m,是因为它求的是第i个数的前m个数中的最小值
		while(head<=rear&&b[head]<i-m){
			head++;
		}
		printf("%d\n",a[b[head]]);
		while(head<=rear&&a[b[rear]]>a[i]){
			rear--;
		}
		b[++rear]=i;
	}
	return 0;

}

代码2(STL单调队列):

#include<bits/stdc++.h>
using namespace std;
const int N=2000005;
int n,m,a[N],b[N];
deque<int> q;
//快读函数:
//设置一个变量用于标记数的正负,一个变量用来记录数的大小
inline int read(){
    char a;
    int f=1,x=0;
    a=getchar();
    //先读入数据的符号,如果是负号,就将f变为-1
    while(a<='0'||a>='9'){
        if(a=='-'){
            f=-1;
        }
        a=getchar();
    }
    //读入数据
    while(a>='0'&&a<='9'){
        x=x*10+a-'0';
        a=getchar();
    }
    return x*f;
}
int main(){
    n=read();m=read();
    b[0]=0;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<n;i++){
       while(!q.empty()&&a[q.back()]>a[i]){
        q.pop_back();
       }
       q.push_back(i);
       while(!q.empty()&&q.front()<=i-m){
        q.pop_front();
       }
       b[i]=a[q.front()];
    }
    for(int i=0;i<n;i++){
        printf("%d\n",b[i]);
    }
    return 0;
}
//快写函数:如果数大于10,就一位一位输出,用递归调用
//如果是小于10的数,则输出对应的字符
//void write(int x){
//	if(x>10) write(x/10);
//	putchar(x%10+'0');
//}

注意点:

1.一定要注意题目的输出的格式

2.本题目是求第i个数的前m个数中的最小值(不包括第i个数)

读写速度差异比较:

1.cin cout最慢

2.ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)与scanf和printf差不多,但是还是慢与scanf和printf

3.printf与scanf与前两者都快

4.快写函数和快读函数比3快(以字符串的形式),getchar ()和putchar()

快读函数:

inline int read(){
    char a;
    int f=1,x=0;
    a=getchar();
    //先读入数据的符号,如果是负号,就将f变为-1
    while(a<='0'||a>='9'){
        if(a=='-'){
            f=-1;
        }
        a=getchar();
    }
    //读入数据
    while(a>='0'&&a<='9'){
        x=x*10+a-'0';
        a=getchar();
    }
    return x*f;
}

快写函数:

void write(int x){
	if(x>10) write(x/10);
	putchar(x%10+'0');
}