洛谷 P1886 滑动窗口(单调队列)

题目原网址:https://www.luogu.org/problemnew/show/P1886

解题思路:

维护一个单调队列,

假如我们先求最小值,保证队首就是最小值,满足滑动窗口长度时输出队首;

例如样例 1 3 -1 -3 5 3 6 7

第一步 1 先入队了

第二步  1 小于3 没问题 所以3接着入队了

第三步   1和3 都大于-1 所以1和3都弹出  -1入队  此时刚好满足长度为k(k=3)的滑动窗口,输出队首 -1

第四步  -1 大于 -3 所以-1弹出 -3 入队  输出队首-3

第五步 -3 小于5 没问题  5入队 输出队首-3

第六步  5大于3  那5不论怎么样都不可能是最小值了,所以弹出5  ,3入队,输出队首-3

第六步  3小于6没问题  6入队,此时滑动窗口覆盖范围已经走到了(5,3,6) 所以要将-3 出队,输出队首3

第七步 6小于7没问题   ,7入队,输出队首3

 求最大值的话同理

//以上转载自:https://www.cnblogs.com/llke/p/10780121.html

AC代码:

  1 #include<cstdio>
  2 #include<queue>
  3 #include<iostream>
  4 
  5 using namespace std;
  6 
  7 deque<int> l;
  8 queue<int> _min,_max;
  9 int n,k,num[1000001];
 10 
 11 void findmin() {
 12     int minid = 1,o,minn = 0x7f7f7f,ts;
 13     for(int i = 1;i <= k; i++) {
 14         if(l.empty()) 
 15             l.push_back(i);
 16         o = num[i];
 17         if(o <= minn) {
 18             minn = o;
 19             minid = i;
 20             while(!l.empty()) {
 21                 o = l.front();
 22                 if(num[o] >= minn) 
 23                     l.pop_front();
 24                 else break;
 25             }
 26             l.push_front(minid);
 27         }
 28         else {
 29             while(!l.empty()) {
 30                 o = l.back();
 31                 if(num[o] >= num[i]) 
 32                     l.pop_back();
 33                 else break;
 34             }
 35             l.push_back(i);
 36         }
 37     }
 38     _min.push(minn);
 39     for(int i = k + 1;i <= n; i++) {
 40         if(minid <= i - k) {
 41             l.pop_front();
 42             minid = l.front();
 43             minn = num[minid];
 44         }
 45         if(l.empty()) l.push_back(i);
 46         o = num[i];
 47         if(o <= minn) {
 48             minn = o;
 49             minid = i;
 50             while(!l.empty()) {
 51                 o = l.front();
 52                 if(num[o] >= minn)
 53                     l.pop_front();
 54                 else break;
 55             }
 56             l.push_front(minid);
 57         }
 58         else {
 59             while(!l.empty()) {
 60                 o = l.back();
 61                 if(num[o] >= num[i]) 
 62                     l.pop_back();
 63                 else break;
 64             }
 65             l.push_back(i);
 66         }
 67         _min.push(minn);
 68     }
 69     while(!_min.empty()) {
 70         cout << _min.front() << " " ;
 71         _min.pop();
 72     }
 73     cout << endl;
 74 }
 75 
 76 void findmax() {
 77     int maxid = 1,o,maxx = -0x7f7f7f;
 78     for(int i = 1;i <= k; i++) {
 79         if(l.empty()) 
 80             l.push_back(i);
 81         o = num[i];
 82         if(o >= maxx) {
 83             maxx = o;
 84             maxid = i;
 85             while(!l.empty()) {
 86                 o = l.front();
 87                 if(num[o] <= maxx) 
 88                     l.pop_front();
 89                 else break;
 90             }
 91             l.push_front(maxid);
 92         }
 93         else {
 94             while(!l.empty()) {
 95                 o = l.back();
 96                 if(num[o] <= num[i]) 
 97                     l.pop_back();
 98                 else break;
 99             }
100             l.push_back(i);
101         }
102     }
103     _max.push(maxx);
104     for(int i = k + 1;i <= n; i++) {
105         if(maxid <= i - k) {
106             l.pop_front();
107             maxid = l.front();
108             maxx = num[maxid];
109         }
110         if(l.empty()) l.push_back(i);
111         o = num[i];
112         if(o >= maxx) {
113             maxx = o;
114             maxid = i;
115             while(!l.empty()) {
116                 o = l.front();
117                 if(num[o] <= maxx)
118                     l.pop_front();
119                 else break;
120             }
121             l.push_front(maxid);
122         }
123         else {
124             while(!l.empty()) {
125                 o = l.back();
126                 if(num[o] <= num[i]) 
127                     l.pop_back();
128                 else break;
129             }
130             l.push_back(i);
131         }
132         _max.push(maxx);
133     }
134     while(!_max.empty()) {
135         cout << _max.front() << " ";
136         _max.pop();
137     }
138 }
139 
140 bool tepan() {
141     if(k == 1) {
142         for(int i = 1;i <= n; i++)
143             cout << num[i] << " ";
144         cout << endl;
145         for(int i = 1;i <= n; i++)
146             cout << num[i] << " ";
147         return true;
148     }
149     else return false;
150 }
151 
152 int main() {
153     scanf("%d%d",&n,&k);
154     for(int i = 1;i <= n; i++) 
155         scanf("%d",&num[i]);
156     if(tepan()) return 0;
157     findmin();
158     while(!l.empty()) l.pop_back();
159     findmax();
160     return 0;
161 }

 

转载于:https://www.cnblogs.com/lipeiyi520/p/11237335.html

引用中提到了Redis的三种集群模式,分别是主从模式、Sentinel模式和Cluster模式。主从模式中,一个主节点负责写入操作,而多个从节点负责读取操作和数据备份。Sentinel模式是一种高可用性的方案,通过监控主节点的状态并进行故障转移,确保系统的可用性。Cluster模式Redis官方推荐的分布式解决方案,通过分片的方式将数据分布在多个节点上,实现数据的水平扩展和负载均衡。关于Redis的详细介绍可以参考中的链接。 引用中提到了在备份恢复前的准备工作,在B服务器上进行了数据文件的替换和清空操作。具体步骤包括删除原有数据文件、下载备份数据文件、清空集群数据和删除dump.rdb和aof文件等。这些操作是为了准备好数据文件,以便后续的恢复操作。 引用中提到了当客户端向从服务器发送slaveof命令时,从服务器需要执行同步操作,将自己的数据库状态更新至主服务器当前的状态。这是为了保证从服务器与主服务器的数据保持一致。 综上所述,Redis集群是一种分布式的解决方案,可以通过主从模式、Sentinel模式或Cluster模式来实现。在进行备份恢复时,需要进行一系列的准备工作,如替换数据文件、清空数据和删除原有文件等。而当从服务器向主服务器发送slaveof命令时,需要进行同步操作,以保持数据的一致性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Redis集群详解](https://download.csdn.net/download/weixin_38714370/13682522)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [redis集群数据同步](https://blog.csdn.net/T_LOYO/article/details/128373960)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Redis集群系列八 —— 集群间数据同步原理](https://blog.csdn.net/xhaimail/article/details/128449489)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值