zoukankan      html  css  js  c++  java
  • 滑动窗口

    题目

    有一个数列,长度为 (n) 。有 (q) 个询问,每次询问所有长度为 (k) 的区间的最大值之和。
    (qleq 1e6)(nleq 1e6)(kin [1,n])

    题解

    先拆一波贡献,把答案转化为每一个数对与每一个询问的贡献。
    可以发现,一个数对一个询问有贡献(即被当做最大值取到),当且仅当这个区间包括它,但不包括它前面第一个比它大的那个数和他后面第一个比他大的数。
    它前面第一个比它大的那个数和他后面第一个比他大的数可以单调栈 (Theta (n))
    然后对询问建线段树,考虑序列中的一个数,它和它前面第一个比它大的那个数的下标之差(也就是距离)为(x),它和它后面第一个比它大的那个数的下标之差为 (y) ,不妨令 (xleq y)
    那么,这个数字对于(1)(n)询问的贡献可以分为三段:
    (1. kin (0,x]) :贡献为 (k)
    (2. kin (x,y]) :贡献为 (x)
    (3. kin (y,n]) :贡献为 (x+y-k)。(可能具体边界上还有需要修正的地方,但大概就是这个意思)
    那么,我们可以发现,第一段和第三段是区间加等差数列,第二段是区间加,这都可以用线段树来很好的维护。
    复杂度 (Theta (nlog_{2}n))

    感谢 (Qiuly) 帮补了一些 (LaTeX)

  • 相关阅读:
    Java之内部类
    java之对象的前世今生
    java之继承
    java之接口
    何为大学 大学何为?
    丁香般的姑娘
    MySQL创建数据库与创建用户以及授权
    CentOS6.8手动安装MySQL5.6
    linux 修改myql 编码配置等信息参考
    Centos6.8 Mysql5.6 安装配置教程
  • 原文地址:https://www.cnblogs.com/thedreammaker/p/13160361.html
Copyright © 2011-2022 走看看