洛谷P1886 滑动窗口
作者:互联网
典型的RMQ问题, 无需过多的解释。
一开始想用刚学的线段树, 于是费了九牛二虎之力打了个线段树,结果
具体为毛WA, 求大佬们指点。
然后我只好默默打了个ST表。
ST表这东西嘛, 真不错,简单粗暴,比线段树好调多了,然后就
就在这时, 我突然意识到其实不用开两个数组, 重复利用一个没准也可以水过去。 结果数据真的让我水过去了。
Code
#include <iostream> #include <cstdio> using namespace std; //Benjamin //(ST表)100分 #define maxn 1000010 int log[maxn], f[1000001][20], a[maxn]; //空间所迫,这里不允许我们开两个fmax[][]和fmin[][]同时做,所以用牺牲时间的方式换取空间 int n, k, x, y; int main() { scanf("%d%d", &n, &k); //接下来的步骤就基本上是ST表的模板了。 log[0] = -1; for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); log[i] = log[i>>1] + 1; f[i][0] = a[i]; } for(int j = 1; j <= 20; j++) { for(int i = 1; i + (1<<j) -1 <= n; i++) { f[i][j] = min(f[i][j-1], f[i + (1<<j-1)][j-1]); } } int m = n - k + 1; for(int i = 1; i <= m; i++) { int s = i + k - 1; int ss = log[s - i + 1]; printf("%d ", min(f[i][ss], f[s - (1<<ss) + 1][ss])); } printf("\n"); //重新再做一遍 for(int i = 1; i <= n; i++) f[i][0] = a[i]; for(int j = 1; j <= 20; j++) { for(int i = 1; i + (1<<j) -1 <= n; i++) { f[i][j] = max(f[i][j-1], f[i + (1<<j-1)][j-1]); } } for(int i = 1; i <= m; i++) { int s = i + k - 1; int ss = log[s - i + 1]; printf("%d ", max(f[i][ss], f[s - (1<<ss) + 1][ss])); } return 0; }
ST表大法好!!!
标签:洛谷,log,P1886,线段,ST,int,maxn,滑动,include 来源: https://www.cnblogs.com/Benjamin-cpp/p/10371755.html