单调队列板子题。第一次新学,仍需继续努力练习。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /* 洛谷 P1886 滑动窗口 STL程序(各种优化都做的不大好,时间略长,但能AC) “单调队列”数据结构 参考文档: 1、https://blog.csdn.net/a_bright_ch/article/details/77076228 2、https://blog.csdn.net/zhelong3205/article/details/77624699 3、https://blog.csdn.net/er111er/article/details/78344161 4、https://www.luogu.org/blog/hankeke/solution-p1886 建议真心想学的可以参考材料自己动手写一个。 */ #include<iostream> #include<algorithm> #include<cstdio> #include<string> #include<deque> using namespace std; int n, k; int arr[1000005]; deque<int> dq,pq; int main() { ios::sync_with_stdio(false); cin >> n >> k; for (int i = 1; i <= n; i++)cin >> arr[i]; //单调队列求最小 for (int i = 1; i <= n; i++) { //维护队尾并插入 while (!dq.empty() && dq.back() > arr[i]) { //求最大和最小的区别在第二个条件是大于号还是小于号 dq.pop_back(); pq.pop_back(); } dq.push_back(arr[i]); pq.push_back(i); //剔除无效队首并获得最优解 while (!pq.empty() && pq.back() - pq.front() >= k) { dq.pop_front(); pq.pop_front(); } if (i >= k)cout << dq.front() << " "; } cout << endl; dq.clear(); pq.clear(); //单调队列求最大 for (int i = 1; i <= n; i++) { //维护队尾并插入 while (!dq.empty() && dq.back() < arr[i]) { //求最大和最小的区别在第二个条件是大于号还是小于号 dq.pop_back(); pq.pop_back(); } dq.push_back(arr[i]); pq.push_back(i); //剔除无效队首并获得最优解 while (!pq.empty()&&pq.back() - pq.front() >= k) { dq.pop_front(); pq.pop_front(); } if (i >= k)cout << dq.front()<< " "; } } |