CodeForces 1098E. Fedya the Potter
题目简述:给定长度为$n \leq 5\times 10^4$的序列$a_1, a_2, \dots, a_n \leq 10^5$。将$\gcd(a_l, a_{l+1}, \dots, a_r) (1 \leq l \leq r \leq n) $从小到大排序后得到长度为$n(n+1)/2$的序列$b$。将$b_l+b_{l+1}+\dots+b_r (1 \leq l \leq r \leq n(n+1)/2)$从小到大排序后得到序列$c$。求$c$的中位数。
注:若$c$的下标从$1$开始,则$c$的中位数定义为其第$\lfloor (k+1)/2 \rfloor$个元素。
解:
这题可分成明显的几个步骤。
Step 1:统计不同的$\gcd$
相关题目:[NOI2012]魔幻棋盘
固定$i$,令$g(j) = \gcd\{a_i, a_{i+1}, \dots, a_j\} (1 \leq i \leq j \leq n)$,则$g(j) | a_i$且$g(j)$单调递减,从而不相同的$g(j)$的个数$= O(\log a_i)$。于是序列$b$中互不相同的元素个数只有$O(n \log V)$,其中$V = \max_i \{a_i\}$为序列$a$的最大值。
根据$g(j)$的单调性,可以通过二分法依次求出所有不同的$g(j)$及其个数。
为了能在二分时对任意$1 \leq l \leq r \leq n$,快速计算出$\gcd(a_l, a_{l+1}, \dots, a_r)$,我们需要用倍增思想预处理出$d[i][k] = \gcd (a_i, a_{i+1}, \dots, a_{i+2^k-1})$,其递推式为
$$ d[i][k] = \gcd(d[i][k-1], d[i+2^{k-1}][k-1]). $$
预处理$d[i][k]$时间复杂度为$O(n \log n \log V)$。对某个$i$,统计出所有不同的$g(j)$及其个数,需要至多使用二分法$O(\log V)$次,二分法需要二分$O(\log n)$步,每步需要计算$\gcd$的复杂度为$O(\log V)$,故总时间复杂度为$O(n \log n \log^2 V)$。
Step 2:二分$c$的中位数
相关题目:AtCoder Regular Contest 101 D. Median of Medians
使用二分法求$c$的中位数$m$,于是问题转化为统计$c$中$\geq x$的数的个数$t$。由于$c$中元素个数为$N(N+1)/2$,其中$N = n(n+1)/2$,若$t \geq \lfloor (N+1)/2 \rfloor$,则说明$x \geq m$,否则$x < m$。二分法的上界是需要估计一下的,最坏情况$a_1 = a_2 = \dots = a_n = V$,这时$b_i = V$,$c$的最大值为$V n(n+1)/2 < 1.3 \times 10^{14}$。故需要$O(\log (Vn(n+1)/2) ) = O(\log V + \log n)$步。
记$b[v]$表示$v$在$b$中出现的次数,$b[l \dots r]$表示$l \dots r$在$b$中出现的次数,以及
$$ S[v] = \sum_{k=1}^v k b[k] $$
表示所有$\leq v$的元素之和,简记$S[l \dots r] = S[l]+\dots+S[r]$。
对给定的$x$,我们枚举$i$,计算以$i$为最大元素的$b_l+b_{l+1}+\dots+b_r \leq x$求和的个数,简称为$b$求和(我们把$c$中的一个元素成为一个$b$求和)。
1. 若$S[i] \leq x$,则任意一个以$i$为最大元素的$b_l+b_{l+1}+\dots+b_r$求和均$\leq x$,故满足条件的$b$求和个数为
$$ \sum_{k=1}^{b[i]} (b[1 \dots i-1]+k) = b[i] b[1\dots i-1]+\frac 1 2 b[i] (b[i]+1). $$
2. 若$S[i] > x$,枚举$i$出现的次数$1 \leq l \leq b[i]$,找到最小的$j < i$,使得$S[j+1 \dots i-1]+li \leq x$,则以$i$为最大元素且个数至少为$l$,$j$为最小元素的$b$求和个数为
$$ \sum_{k=l}^{b[i]} \max \left\{ \min \left\{ \left\lfloor \frac {x-S[j+1 \dots i-1]-ki} {j} \right\rfloor, b[j] \right\} , 0 \right\}. $$
我们只需考虑$x-S[j+1 \dots i-1]-ki > 0$的情况,即$k<(x-S[j+1 \dots i-1])/i$。令$r = \min\left\{ b[i], \left\lfloor (x-S[j+1 \dots i-1])/ i \right\rfloor \right\}$,从而以上求和化为
$$ \sum_{k=l}^{r} \min \left\{ \left\lfloor \frac {x-S[j+1 \dots i-1]-ki} {j} \right\rfloor, b[j] \right\}. $$
此式可化为
$$ \sum_{k=l}^r \left\lfloor \frac {x-S[j+1 \dots i-1]-ki} {j} \right\rfloor - \sum_{k=l}^r \max \left\{ \left\lfloor \frac {x-S[j+1 \dots i-1]-ki} {j} \right\rfloor - b[j], 0 \right\} $$
即
$$ \sum_{k=0}^{r-l} \left\lfloor \frac {x-S[j+1 \dots i-1]-li-ki} {j} \right\rfloor - \sum_{k=0}^{r-l} \max \left\{ \left\lfloor \frac {x-S[j+1 \dots i-1]-li-ki-jb[j]} {j} \right\rfloor , 0 \right\} $$
化简为
$$ f(-i, x-S[j+1 \dots i-1]-li, j, r-l) - f(-i, x-S[j+1 \dots i-1]-li-jb[j], j, r-l), $$
其中
$$ f(a,b,c,n) = \sum_{k=0}^n \max \left\{ \left\lfloor \frac {ak+b} {c} \right\rfloor, 0 \right\}. $$
特别地,若不存在$j < i$,使得$S[j+1 \dots i-1]+li \leq x$,则以$i$为最大元素且至少有$l$个的$b$求和个数为
$$ \sum_{k=l}^{b[i]} \min \left\{ k, \left\lfloor \frac x i \right\rfloor \right\}. $$
Step 3: 计算$f(a, b, c, n)$
我们需要把$f(a,b,c,n)$转化为$a, b, c, n \geq 0$的情形。
若$n < 0$,则$f(a,b,c,n) = 0$。
若$c < 0$,可利用$f(a,b,c,n) = f(-a, -b, -c, n)$使得$c > 0$。
若$c > 0$但$a < 0$,可利用$f(a,b,c,n) = f(-a,b+an,c,n)$使得$c > 0$且$a > 0$。
若$c > 0, a > 0$但$b < 0$,可利用$f(a,b,c,n) = f(a, b+\lceil -b/a \rceil a, c, n-\lceil -b/a \rceil)$使得$a, b, c > 0$。
当$a, b, c > 0$时,$f(a,b,c,n)$可化为范式
$$ f(a,b,c,n) = \sum_{k=0}^n \left\lfloor \frac {ak+b} {c} \right\rfloor. $$
我们用Euclid算法计算$f(a,b,c,n)$。
1. 若$n = 0$,则$f(a,b,c,n) = \lfloor b/c \rfloor (n+1)$。
2. 若$a \geq c$或$b \geq c$,令$a = \lfloor a/c \rfloor c+a', b = \lfloor b/c \rfloor c+b'$,则
$$ f(a,b,c,n) = \sum_{k=0}^n \left\lfloor \frac {(\lfloor a/c \rfloor c+a')k+(\lfloor b/c \rfloor c+b')} {c} \right\rfloor = f(a', b', c, n)+\frac 1 2 n(n+1) \left\lfloor \frac {a} {c} \right\rfloor + (n+1) \left\lfloor \frac {b} {c} \right\rfloor. $$
3. 若$a,b < c$,令$m = \left\lfloor \frac {an+b} {c} \right\rfloor$,则
$$ \begin{aligned} f(a,b,c,n) & = \sum_{k=1}^n \left\lfloor \frac {ak+b} {c} \right\rfloor \\ & = \sum_{x=1}^n \sum_{y=1}^m \left[ \frac {ax+b} {c} \leq y \right] \\ & = \sum_{y=1}^m \sum_{x=1}^n \left[ \frac {cy-b} {a} \geq x \right] \\ & = nm-\sum_{y=1}^m \sum_{x=1}^n \left[ \frac {cy-b} {a} < x \right] \\ & = nm-\sum_{y=1}^m \left( \left\lfloor \frac {cy-b} {a} \right\rfloor - [a|(cy-b)] \right) \\ & = nm-\sum_{y=1}^m \left\lfloor \frac {cy-b-1} {a} \right\rfloor \\ & = nm-\sum_{y=0}^{m-1} \left\lfloor \frac {cy+c-b-1} {a} \right\rfloor \\ & = nm-f(c, c-b-1, a, m-1) \end{aligned} $$
Euclid辗转相除法的时间复杂度为$O(\log \min \{ a, b \})$。
算法总时间复杂度为$O(n \log n \log^2 V + V \log V (\log n+\log V))$。
CodeForces 1098E. Fedya the Potter的更多相关文章
- CF1098E Fedya the Potter
CF1098E Fedya the Potter 题意:有一个序列\(A\). 对所有\(1\leq l\leq r\leq |A|\),将\(\gcd_{i=l}^{r}A_i\)加入\(B\)中. ...
- Codeforces 456B Fedya and Maths 打表找规律
Description Fedya studies in a gymnasium. Fedya's maths hometask is to calculate the following expre ...
- 【codeforces 65A】Harry Potter and Three Spells
[题目链接]:http://codeforces.com/problemset/problem/65/A [题意] 你有3种魔法; 1.可以将a单位的石头变成b单位的铅 2.可以将c单位的铅变成d单位 ...
- 退役前的最后的做题记录upd:2019.04.04
考试考到自闭,每天被吊打. 还有几天可能就要AFO了呢... Luogu3602:Koishi Loves Segments 从左向右,每次删除右端点最大的即可. [HEOI2014]南园满地堆轻絮 ...
- hs-black 杂题选讲
[POI2011]OKR-Periodicity 考虑递归地构造,设 \(\text{solve(s)}\) 表示字典序最小的,\(\text{border}\) 集合和 \(S\) 的 \(\tex ...
- Codeforces 260 B. Fedya and Maths
题目链接:http://codeforces.com/contest/456/problem/B 解题报告:输入一个n,让你判断(1n + 2n + 3n + 4n) mod 5的结果是多少?注意n的 ...
- Codeforces Round #260 (Div. 2) B. Fedya and Maths
B. Fedya and Maths time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Codeforces - 65D - Harry Potter and the Sorting Hat - 简单搜索
https://codeforces.com/problemset/problem/65/D 哈利波特!一种新思路的状压记忆化dfs,记得每次dfs用完要减回去.而且一定是要在dfs外部进行加减!防止 ...
- CF456B Fedya and Maths 找规律
http://codeforces.com/contest/456/problem/B CF#260 div2 B Fedya and Maths Codeforces Round #260 B. F ...
随机推荐
- Allegro16.6和17.0和17.2中将板框导出DXF文件
Allegro16.6和17.0和17.2中将板框导出DXF文件 转载 https://blog.csdn.net/pieces_thinking/article/details/69817600 标 ...
- 基于django做增删改查组件,分页器组件
增删改查组件 一.Djangoadmin的启发 二.基于Djangoadmin实现数据的增删改查 分页器组件 分页器组件的介绍以及源码解读 补充:源码下载,
- caffe搭建以及初步学习--win7-vs2013-gtx650tiboost-cuda8.0-cifar10训练和测试-2-完整解决方案cifar10_full_solver.prototxt
首先总结前一节的内容. 简单的讲,就是训练并测试了快速解决方案. 转换数据格式: convert_cifar_data.exe data/cifar10 examples/cifar10 lmdb 计 ...
- C语言宏定义时#(井号)和##(双井号)作用
#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量 通过替换后在其左右各加上一个双引号. #define example(instr) prin ...
- MapReduce 1工作原理图文详解
MapReduce工作原理图文详解 一 MapReduce程序执行流程 程序执行流程图如下: 流程分析:1.在客户端启动一个作业.2.向JobTracker请求一个Job ID.3.将运行作业所需要的 ...
- [ExtJS5学习笔记]第五节 使用fontawesome给你的extjs5应用添加字体图标
本文地址:http://blog.csdn.net/sushengmiyan/article/details/38458411本文作者:sushengmiyan-------------------- ...
- javascript 获取当前日期 月份 时间
<script type="text/javascript"> function getDate() { var date = new Date(); //得到当前日期 ...
- c#冒泡法排序
1.通过冒泡法实现一个int数组的有小到大的排序 代码如下: //用for语句来实现排序功能,冒泡排序 static void Sort(int[] number) { ; i < number ...
- Kotlin基本语法笔记3之定义类、继承及创建实例
定义类 class MyObject private constructor(name: String, age: Int) { private var name: String private va ...
- MongoDB 学习五:索引
这章我们介绍MongoDB的索引,用来优化查询. 索引介绍 数据库索引有些类似书的目录. 一个查询如果没有使用索引被称为表扫描,意思是它必须像阅读整本书那样去获取一个查询结果.一般来说,我们应尽量避免 ...