题目描述
Wind 设计了很多机器人。但是它们都认为自己是最强的,于是,一场比赛开始了……
机器人们都想知道谁是最敏捷的,于是它们进行了如下一个比赛。首先,他们面前会有一排共 n 个数,它们比赛看谁能最先把每连续 k 个数中最大和最小值写下来,当然,这些机器人运算速度都很快,它们比赛的是谁写得快。
但是 Wind 也想知道答案,你能帮助他吗?
输入格式
第一行为 n,k,意义如题目描述。
第二行共 n 个数,为数字序列,所有数字均在 Pascal
的 longint
范围内,即所有数均为整数,且在 [?2^31,2^31?1]之间31??,2?31???1] 范围内。
输出格式
共 n?k+1行,第 i 行为第 i至第 i+k?1 这 k 个数中的最大和最小值。
样例
样例输入
5 3
1 2 3 4 5
样例输出
3 1
4 2
5 3
数据范围与提示
对于全部数据,1≤k≤n≤10^5, 第 i 行为第 i 至第 i+k?1 这 k 个数中的最大和最小值。
#include<cstdio> #include<iostream> #define RI register int using namespace std; const int maxn = 1000010; int llog[maxn]; int f[maxn][20]; int g[maxn][20]; int n, k; inline void qread(int &x) { x = 0; register int ch = getchar(), flag = 0; while(ch < ‘0‘ || ch > ‘9‘) { if(ch == ‘-‘) flag = 1; ch = getchar(); } while(ch >= ‘0‘ && ch <= ‘9‘) { x = 10 * x + ch - 48; ch = getchar(); } if(flag) x = -x; } int main(void) { qread(n); qread(k); for(RI i = 2; i <= n; ++i) llog[i] = llog[i >> 1] + 1; for(RI i = 1; i <= n; ++i) qread(f[i][0]); for(RI i = 1; i <= n; ++i) g[i][0] = f[i][0]; for(int i = 1; i <= llog[k]; ++i) for(int j = 1; j <= n; ++j) { f[j][i] = max(f[j][i - 1], f[j + (1 << (i - 1))][i - 1]); g[j][i] = min(g[j][i - 1], g[j + (1 << (i - 1))][i - 1]); } for(int i = 1; (i + k - 1) <= n; ++i) { printf("%d ", max(f[i][llog[k]], f[i + k - (1 << llog[k])][llog[k]])); printf("%d\n", min(g[i][llog[k]], g[i + k - (1 << llog[k])][llog[k]])); } }
思路:
ST表,注意数组要开大些,否则可能爆内存
5??。
原文地址:https://www.cnblogs.com/junk-yao-blog/p/9472294.html
时间: 2024-10-08 02:08:55