洛谷P1886 滑动窗口(POJ.2823 Sliding Window)(区间最值)

To 洛谷.1886 滑动窗口 To POJ.2823 Sliding Window

题目描述

现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。

例如:

The array is [1 3 -1 -3 5 3 6 7], and k = 3.

输入输出格式

输入格式:

输入一共有两行,第一行为n,k。

第二行为n个数(<INT_MAX).

输出格式:

输出共两行,第一行为每次窗口滑动的最小值

第二行为每次窗口滑动的最大值

输入输出样例

输入样例#1:

8 3
1 3 -1 -3 5 3 6 7

输出样例#1:

-1 -3 -3 -3 3 3
3 3 5 5 6 7

说明

50%的数据,n<=10^5

100%的数据,n<=10^6

代码:

洛谷70分TLE的线段树

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int N=1000005;
 5
 6 int n,k,From,To,Min[N<<2],Max[N<<2];
 7
 8 void read(int &now)
 9 {
10     now=0;int f=1;char c=getchar();
11     while(c<‘0‘||c>‘9‘)
12     {
13         if(c==‘-‘)f=-1;
14         c=getchar();
15     }
16     while(c>=‘0‘&&c<=‘9‘)now=now*10+c-‘0‘,c=getchar();
17     now*=f;
18 }
19
20 inline void PushUp(int rt)
21 {
22     Min[rt]=min(Min[rt<<1],Min[rt<<1|1]);
23     Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
24 }
25
26 void Build(int l,int r,int rt)
27 {
28     if(l==r)
29     {
30         int t;
31         read(t);
32         Min[rt]=Max[rt]=t;
33         return;
34     }
35     int m=(l+r)>>1;
36     Build(l,m,rt<<1);
37     Build(m+1,r,rt<<1|1);
38     PushUp(rt);
39 }
40
41 int QueryMax(int l,int r,int rt,int L,int R)
42 {
43     if(L<=l && r<=R) return Max[rt];
44     int m=(l+r)>>1,res=(1<<31);
45     if(L<=m) res=max(res,QueryMax(l,m,rt<<1,L,R));
46     if(m<R) res=max(res,QueryMax(m+1,r,rt<<1|1,L,R));
47     return res;
48 }
49
50 int QueryMin(int l,int r,int rt,int L,int R)
51 {
52     if(L<=l && r<=R) return Min[rt];
53     int m=(l+r)>>1,res=(1<<30);
54     if(L<=m) res=min(res,QueryMin(l,m,rt<<1,L,R));
55     if(m<R) res=min(res,QueryMin(m+1,r,rt<<1|1,L,R));
56     return res;
57 }
58
59 int main()
60 {
61     read(n);read(k);
62     Build(1,n,1);
63     //From=1;To=k;
64     for(register int i=1;i<=n-k+1;i++)//,From++,To++
65       printf("%d ",QueryMin(1,n,1,i,i+k-1));
66     printf("\n");
67     //From=1;To=k;
68     for(register int i=1;i<=n-k+1;i++)//,From++,To++
69       printf("%d ",QueryMax(1,n,1,i,i+k-1));
70     return 0;
71 }

TLE

常数优化十分可观的zkw线段树(然而我不会用)

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int N=1000005;
 5
 6 int n,k,M,Tree[N<<2];
 7
 8 void read(int &now)
 9 {
10     now=0;int f=1;char c=getchar();
11     while(c>‘9‘||c<‘0‘)
12     {
13         if(c==‘-‘)f=-1;
14         c=getchar();
15     }
16     while(c>=‘0‘&&c<=‘9‘)now=(now<<3)+(now<<1)+c-‘0‘,c=getchar();
17     now*=f;
18 }
19
20 void BuildMin(int n)
21 {
22     for(int i=M-1;i;--i)
23       Tree[i]=min(Tree[i<<1],Tree[i<<1|1]);
24 }
25
26 void BuildMax(int n)
27 {
28     for(int i=M-1;i;--i)
29       Tree[i]=max(Tree[i<<1],Tree[i<<1|1]);
30 }
31
32 int QueryMin(int s,int t,int res)
33 {
34     for(s+=M,t+=M;s^t^1;s>>=1,t>>=1)
35     {
36         if(~s&1) res=min(res,Tree[s^1]);
37         if(t&1) res=min(res,Tree[t^1]);
38     }
39     return res;
40 }
41
42 int QueryMax(int s,int t,int res)
43 {
44     for(s+=M,t+=M;s^t^1;s>>=1,t>>=1)
45     {
46         if(~s&1) res=max(res,Tree[s^1]);
47         if(t&1) res=max(res,Tree[t^1]);
48     }
49     return res;
50 }
51
52 int main()
53 {
54     read(n);read(k);
55     for(M=1;M<=n+1;M<<=1);
56     for(int i=M+1;i<=M+n;i++)
57       read(Tree[i]);
58     BuildMin(n);
59     for(int i=0;i<=n-k;++i)
60       printf("%d ",QueryMin(i,i+k+1,1e9));
61     printf("\n");
62     BuildMax(n);
63     for(int i=0;i<=n-k;++i)
64       printf("%d ",QueryMax(i,i+k+1,-1e9));
65     return 0;
66 }

AC

时间: 2024-10-22 07:03:09

洛谷P1886 滑动窗口(POJ.2823 Sliding Window)(区间最值)的相关文章

洛谷P1886 滑动窗口 单调队列

洛谷P1886 滑动窗口 单调队列 求一个固定长度的区间 最小值和最大值 单调队列求最小值时 1.刚要插入一个数 判断 其是否 小于等于 队尾的数 如果是 则将队尾的数出队 因为求的是队尾到之前的 最小值 ,所以其已经不可能成为 最小值了2.然后数字进队 3.如果队头 已经不再这个区间中,那就队头出队 最大值也是同理 1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cs

洛谷P1886 滑动窗口

P1886 滑动窗口 454通过 1.4K提交 题目提供者darkfire 标签云端↑ 难度普及+/提高 时空限制1s / 128MB 提交  讨论  题解 最新讨论更多讨论 滑动窗口 求标明空间限制 一个奇怪的问题 水印233 为什么会wa一个点,求dalao- 求大神指点 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array is [1 3 -1 -3 5

洛谷 P1886 滑动窗口

题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array is [1 3 -1 -3 5 3 6 7], and k = 3. 输入输出格式 输入格式: 输入一共有两行,第一行为n,k. 第二行为n个数(<INT_MAX). 输出格式: 输出共两行,第一行为每次窗口滑动的最小值 第二行为每次窗口滑动的最大值 输入输出样例 输入样例#1: 8 3 1 3 -1 -

洛谷P1886滑动窗口

题目传送门 理解题意:给定一个数列和窗口范围k,求依次向右移动窗口时每次窗口内的最大和最小值. 没什么思维难度,普及+/提高的标签纯粹是吓唬人的,一边扫过去,用两个数组maxx和minn记录每个窗口内的最大最小值,移动过程中用两个变量L和R记录窗口的左右端点,然后判断滑动窗口时最大最小值是否被移出窗口,进入窗口的值是否大于当前最大值或小于当前最小值,做完后L++,R++,用while循环控制轻松水过这题.当然,如果数据比较极端故意卡时就可能没这么轻松了.(不过我估计也不太可能会有什么题目出这么可

洛谷 P1886 滑动窗口 (数据与其他网站不同。。)

题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array is [1 3 -1 -3 5 3 6 7], and k = 3. 输入输出格式 输入格式: 输入一共有两行,第一行为n,k. 第二行为n个数(<INT_MAX). 输出格式: 输出共两行,第一行为每次窗口滑动的最小值 第二行为每次窗口滑动的最大值 输入输出样例 输入样例#1: 8 3 1 3 -1 -

POJ 2823 Sliding Window 【单调队列】

题目链接:http://poj.org/problem?id=2823 题目大意:给出一组数,一个固定大小的窗口在这个数组上滑动,要求出每次滑动该窗口内的最大值和最小值. 这就是典型的单调队列,单调队列的作用就在此.单调队列的队首为区间内的最值,但是整个队列不用保持单调. 用两个队列分别处理最大值和最小值,在此说明一下最大值: 往队列中添加值num时,从队尾开始扫,直到遇到一个小于num的d值,将num插入d的后一位.之后的元素全部无效化(不管后面的元素就行).查找最大值的时候,从队首开始找,如

poj 2823 Sliding Window

poj 2823 Sliding Window 单调队列 单调队列是一个单调的状态(递增,或者递减) 所以需要维护这么一个状态 http://baike.baidu.com/link?url=ZcGM7Hzo8zVQUU6Oqqq18SlCMJ92ts3I1aXwQGDZw_NiDDlzIIV9GKlfs3X1fcHVppZHOU31geHZG4cOcRZOAK 固定 k 区间的单调 队列,求 最小值,如果 两个元素 A B ,如果 A 的 下标 比 B 小,但是 A 的 值 比 B 大,那么在

[ACM] poj 2823 Sliding Window(单调队列)

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 36212   Accepted: 10723 Case Time Limit: 5000MS Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left

[ACM] poj 2823 Sliding Window (单调队列)

高一时,学校组织去韶山游玩,我没去,这次趁着五一,总算去了我心心念念的韶山.其实我知道所有的景点都是差不多的,可是因为电视剧<恰同学少年>,让我对毛泽东有了进一层的了解,所以,我一直都想去看看. 有两个同学一男一女是我理想的旅友,可是女生不想去,而男士回家了.所以,我独自一人去了. 准备工作:一小包饼干,一小包山楂片,两个苹果,一瓶水,帽子(防晒),墨镜(装酷) 早晨5:30起床了,洗漱完毕,吃完早餐,赶到公交车站牌那里,才6点过几分.公交车6:31才到,等了近半个小时(公交车上明明说是6:0