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)

  • 相关阅读:
    xgzc— math 专题训练(一)
    floyd判圈算法
    CF961G Partitions
    luoguP4778 Counting swaps
    AT3913 XOR Tree(巧妙转换+状压dp)
    手动实现aop编程
    代理模式
    spring重点一:处理对象创建时间 个数以及方式
    spring helloword
    spring用来干什么,解决的问题
  • 原文地址:https://www.cnblogs.com/thedreammaker/p/13160361.html
Copyright © 2011-2022 走看看