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 ...
随机推荐
- linux查找文件夹下的全部文件里是否含有某个字符串
查找文件夹下的全部文件里是否含有某个字符串 find .|xargs grep -ri "IBM" 查找文件夹下的全部文件里是否含有某个字符串,而且仅仅打印出文件名称 fin ...
- 在Fedora 23上安装多媒体解码器
在Fedora 23上安装多媒体解码器 时间:2016-06-25来源:topspeedsnail.com 作者:斗大的熊猫 安装多媒体解码器允许你播放更多格式的音频和视频格式.大多数这些解码器都 ...
- apktool + eclipse 动态调试APK
用了会AndBug,尽管挺强大的可是作为习惯了OD.EDB作为动态调试工具的人,自然有些不习惯,于是乎寻求新的动态调试解决方式.但大多数都是NetBeans + apktool.想着还得多下一个IDE ...
- Win32对话框工程笔记
Main.cpp #include <Windows.h> #include "resource.h" INT_PTR CALLBACK dialogProc(HWND ...
- TypeSafe Config使用
================typesafeconfig的使用==================== #1.加入依赖包 config-1.2.1.jar #2.加载配置 ConfigFactor ...
- C++ xml 解析器
C++的xml解析器有很多,这个知乎回答里有一个列表:https://www.zhihu.com/question/32046606 下面使用其中的RapidXml试试. 官方地址: https:// ...
- [noip2014day2-T1]无线网路发射器选址
随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129条东西向街道和129条南北向街道所形成的网格状,并且相邻的平行街道之间 ...
- 在ubuntu16.04上编译android源码【转】
本文转载自:http://blog.csdn.net/fuchaosz/article/details/51487585 1 前言 经过3天奋战,终于在Ubuntu 16.04上把Android 6. ...
- JavaScript中浮点数的保留小数位数的问题
方法一 简介:如题! 繁琐版... 代码如下: var significantFigure= function(value,figure){ var arr=(valu ...
- c/c++通用内存泄漏检测框架GMFD(General Memory Fault Detection Framework)
http://qa.baidu.com/blog/?p=171 1 背景: x86平台有完善的用户态检测内存工具比如valgrind等,可以监控程序运行中详细的内存信息,从而精确定位内存问题.然而随着 ...