zoukankan      html  css  js  c++  java
  • 【YBTOJ】【SPOJ 7739】【Luogu P4392】[BOI2007]Sound 静音问题

    链接:

    题目

    博客园

    题目大意:

    求一段数列中,长度为 (m) 的区间最大值减最小值小于等于 (c) 的区间有多少个。

    正文:

    毕竟没有修改的操作,是静态的,用线段树或树状数组显然没必要。提供 ST 表的解法。

    这题要求最大值和最小值,那么就同时开两个数组,分别存最大和最小就行了。时间复杂度 (O(nlog m))

    代码:

    
    int n, m, c;
    int Max[N][12], Min[N][12];
    int secMax(int l, int r)
    {
        int k = log2(r - l + 1); 
        return max(Max[l][k], Max[r - (1 << k) + 1][k]); 
    }
    int secMin(int l, int r)
    {
        int k = log2(r - l + 1); 
        return min(Min[l][k], Min[r - (1 << k) + 1][k]); 
    }
    
    int main()
    {
        scanf ("%d%d%d", &n, &m, &c);
        int lg = log2(m);
        for(int i = 1; i <= n; i++) 
    		scanf ("%d", &Max[i][0]), Min[i][0] = Max[i][0];
        for(int j = 1; j <= lg; j++)
            for(int i = 1; i + (1 << j) - 1 <= n; i++) 
                Max[i][j] = max(Max[i][j - 1], Max[i + (1 << (j - 1))][j - 1]), 
                Min[i][j] = min(Min[i][j - 1], Min[i + (1 << (j - 1))][j - 1]); 
        int flag = 1;
        for (int i = 1; i + m - 1 <= n; i++)
        	if (secMax(i, i + m - 1) - secMin(i, i + m - 1) <= c)
        		printf ("%d
    ", i), flag = 0;
        if (flag) printf("NONE
    ");
        return 0;
    }
    
  • 相关阅读:
    linux ss 命令
    linux netstat 命令
    linux firewalld 命令
    linux sshd 服务
    linux rysnc 命令(远程复制)
    linux scp 命令
    linux ifconfig
    linux /var/log 日志文件
    linux systemctrl 命令
    linux 创建新用户并设置管理员权限
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/14324747.html
Copyright © 2011-2022 走看看