zoukankan      html  css  js  c++  java
  • [Ynoi2019] 魔法少女网站

    • 题意

      给定一个长为 (n) 的序列 ({a}) ,支持:

      1. 单点修改。
      2. 查询区间 ([l,r]) 最大值小于等于 (x) 的子区间个数。

      (n,mle 3 imes 10^5,a_iin [1,n])

      3.5s,64MB​

    • 题解

      容易发现,对于查询操作,我们如果把 (le x) 的数设为 (1) ,其余为 (0) ,那么一个长为 (len) 的极长 (1) 连续段的贡献为 (frac{len(len+1)}{2})

      那么暴力即为从左到右模拟整个过程,维护后缀 (1) 连续段的长度。

      考虑优化这个模拟过程,不难想到序列分块。

      设块长为 (B) ,那么一个块内本质不同的答案只有 (O(B)) 个。

      对于查询区间 ([l,r]) ,边角暴力。对于中间的块,我们需要维护 (le x)(1) 连续段前缀长度,后缀长度,以及除去前后缀的块内贡献。

      如果我们对每个块,从小到大处理每个元素,利用链表或并查集等维护 (1) 连续段,能做到一次 (O(B)) 求出一个块所有本质不同的答案。

      那么我们预处理直接对块内排序,修改就类似插入排序的方式维护排序后的数组,块内信息暴力重构,那么预处理复杂度是 (O(nlog n)) ,修改一次复杂度是 (O(B))

      询问对于一个块我们还需要找到 (x) 的位置,复杂度一次是 (O(B+frac{n}{B}log B))

      不难得出 (B=sqrt{nlog n}) 最优,总复杂度 (O(nlog n+msqrt{nlog n}))

      然而这大概率不能通过这道题,我们继续优化。

      注意到瓶颈在于找到 (x) 在一个块内的位置,这是一个前缀和问题,我们有 (O(sqrt n)-O(1)) 的值域分块,而空间限制导致我们不能对每个块开一个前缀和数组,那么容易想到离线,逐块处理,每次利用 (O(sqrt n)-O(1)) 的值域分块做到 (O(1)) 查询位置。

      我们来分析复杂度。

      预处理不变: (O(nlog n))

      多了新操作每个块的处理: (O(frac{n^2}{B}))

      修改要增加一个值域分块: (O(m(B+sqrt n)))

      查询把 (log B) 去掉: (O(m(B+frac{n}{B})))

      那么 (B=sqrt n) 最优,总复杂度 (O((n+m)sqrt n))

  • 相关阅读:
    [数据库]Mysql蠕虫复制增加数据
    [YII2.0] 高级模板简单安装教程
    PHP 将字符串转换为字符集格式UTF8/GB2312/GBK 函数iconv()
    [腾讯云]简单在腾讯云 CenTOS7.0 安装Nginx,Mysql(MariaDB),Memcache,解析PHP!
    cojs 简单的01串 题解报告
    5.13 考试修改和总结
    cojs 简单的最近公共祖先 解题报告
    5.11 考试 修改+总结
    My_Plan part1 小结
    cojs 简单的数位DP 题解报告
  • 原文地址:https://www.cnblogs.com/leukocyte/p/15037565.html
Copyright © 2011-2022 走看看