zoukankan      html  css  js  c++  java
  • 一类巧妙利用利用分治的序列求值

    I.PreFace

    这个方法经常用于这类问题:

    给定序列 (A),并定义基于序列 (A) 的函数 (f(l, r)),求 (sumlimits_{1 leq i leq j leq n}f(l, r))

    这个方法的核心做用是:

    将不满足可减性的求值,变成只需要可以区间拼合(即满足区间可加性)的求值式子。

    II.常用的解决办法:

    1. 拆成每个点的贡献处理。

    2. 从左到右推进端点 (r),开一个数据结构维护对于当前每个 (l) 的函数值 (f(l,r)),每推进一位 (r) 对应了一次的区间修改和一次的整体求和。

    etc,这不是本文的重点。

    III. 正文

    考虑分治:

    这回我们只要求跨过中点的区间的贡献就够了,即求

    [sum_{i=l}^{mid}sum_{j=mid+1}^{r}f(i,j) ]

    这个式子当然还是是 (O(n^2)) 的,但是常常它比原问题的那个更加的简便,有无穷的威力。简便在哪?简便在于,本来这个式子可能不满足区间可减性,但是经过这样的分治,它只需要区间可加就行了,于是可以转化为第 II 节中的方法。

    设当前求解当前 (mid) 的时间复杂度为 (O(f(r-l+1))),那么总复杂度也就近似的可以认为是 (O(f(n) log n)

    IV. 随便的一道例题:

    给定数列 (A),设 (f(l,r)=maxlimits_{i=l}^{r}A_i),求 (sumlimits_{i=1}^nsumlimits_{j=i}^n f(i,j))

    利用上述转化后问题就变成了可以用第 II 部分中的第一种处理,设 (g(i)) 为前缀/后缀最大值,那么它一定是单调的,即对于每一个位置的最大值的贡献,我就看一下另一边有多少个数小于它即可。尺取法一下复杂度 (nlog n)。事实上还有很多其他解法,这里只是作为一个 example。

    V. 练习题:

    GSOR 1008,谢谢出题人 lxl。

    哈哈哈其实他给的做法都是 (n log^2 n) 的,其实很轻松可以做到 (nlog n),于是就成了最短+最快解(哈哈哈!

    as 0.4123
  • 相关阅读:
    Eclipse安装TestNG插件
    总结Selenium WebDriver中一些鼠标和键盘事件的使用
    【资料收集】AutomationGuru
    centos7.4 yum安装包出现网络不可达跟Recv failure: Connection reset by peer" 这个问题
    ubuntu配置ntp
    OpenStack-ansible ubuntu16.04安装&& centos7 安装 && openSUSE 安装OpenStack-ansible
    HSRP&&STP&&ACL
    vlan通讯&&动态路由
    cisco交换机基本配置
    cisco教程 怎么改console密码 主机名 各种模式的切换等
  • 原文地址:https://www.cnblogs.com/Linshey/p/14165532.html
Copyright © 2011-2022 走看看