码迷,mamicode.com
首页 > 其他好文 > 详细

P4392 [BOI2007]静音问题 题解

时间:2019-08-20 21:49:43      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:oid   problem   表操作   程序   iostream   space   none   信息   元素   

传送门:P3942

这道题要求我们对所有长度为m的序列,找出其中最大值和最小值的差值不超过c的,并输出它们的起始位置。

看到静态序列最值问题,很自然的想到要用ST表进行Θ(nlogn+n)预处理、Θ(1)查询。但是很不幸,如果直接用两个表分别存储最大值和最小值,最后一个点妥妥的MLE,因此我们需要对空间占用进行优化。

考虑到每个序列的长度是固定的,我们可以先进行一次ST表操作,记录下vali= max{ai →ai+m} 。再在同一个f数组中进行第二次ST表操作,计算出fi = min{ai → ai+m},最后1→(n - m)扫描一次各元素,满足条件vali - fi ≤ c时输出i即可。同时,由于序列长度固定为m,所以我们不需要像一般的ST表一样开一个O(nlogn)的数组,开一个O(nlogm)的数组即可存储下全部有效信息,因此第二维可以缩小至 log2m  = 15。经过这两次优化,程序的空间复杂度降低至可以接受的程度,可以开心的A掉这道题。完整代码如下:

#include <iostream>
#include <cstdio>
using namespace std;
int n;
int val[1000010], f[1000005][15];

inline int max(int x, int y){
    return x > y ? x : y;
}

inline int min(int x, int y){
    return x < y ? x : y;
}

inline void init1() {
    for (int i = 1; i <= n; i++) scanf("%d", &f[i][0]);//直接输入,节约空间
    for (int j = 1; j <= 14; 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]);//预处理区间最大值
}
inline void init2() {
    for (int j = 1; j <= 14; 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 k;
int find1(int l, int r) {
    return max(f[l][k], f[r - (1 << k) + 1][k]);//查询区间最大值
}
int find2(int l, int r) {
    return min(f[l][k], f[r - (1 << k) + 1][k]);//查询区间最小值
}

int main() {
    int m, c;
    scanf("%d%d%d", &n, &m, &c);//按题意输入
    init1();//预处理最大值
    while( (1 << (k + 1) ) <= m) k++;//计算出区间长度
    for (int i = 1, j = i + m - 1; j <= n; i++, j++){
        val[i] = find1(i, j);
    }//记录下区间最大值
    init2();//预处理区间最小值
    int ok = 0;//用于记录是否下是否有合法的序列
    for(int i = 1, j = i + m - 1; j <= n; i++, j++){
        if(val[i] - find2(i, j) <= c)
            ok = printf("%d\n", i);
//这里运用了printf函数在成功输出后会返回输出元素个数的性质,只要有输出,ok就会被赋上一个非0值
    }
    if(!ok) puts("NONE");//特判没有合法区间的情况
    return 0;
}

 

 

P4392 [BOI2007]静音问题 题解

标签:oid   problem   表操作   程序   iostream   space   none   信息   元素   

原文地址:https://www.cnblogs.com/begin-AC/p/11385694.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!