题目简述:给定长度为$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$个元素。

解:

code

这题可分成明显的几个步骤。

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的更多相关文章

  1. CF1098E Fedya the Potter

    CF1098E Fedya the Potter 题意:有一个序列\(A\). 对所有\(1\leq l\leq r\leq |A|\),将\(\gcd_{i=l}^{r}A_i\)加入\(B\)中. ...

  2. Codeforces 456B Fedya and Maths 打表找规律

    Description Fedya studies in a gymnasium. Fedya's maths hometask is to calculate the following expre ...

  3. 【codeforces 65A】Harry Potter and Three Spells

    [题目链接]:http://codeforces.com/problemset/problem/65/A [题意] 你有3种魔法; 1.可以将a单位的石头变成b单位的铅 2.可以将c单位的铅变成d单位 ...

  4. 退役前的最后的做题记录upd:2019.04.04

    考试考到自闭,每天被吊打. 还有几天可能就要AFO了呢... Luogu3602:Koishi Loves Segments 从左向右,每次删除右端点最大的即可. [HEOI2014]南园满地堆轻絮 ...

  5. hs-black 杂题选讲

    [POI2011]OKR-Periodicity 考虑递归地构造,设 \(\text{solve(s)}\) 表示字典序最小的,\(\text{border}\) 集合和 \(S\) 的 \(\tex ...

  6. Codeforces 260 B. Fedya and Maths

    题目链接:http://codeforces.com/contest/456/problem/B 解题报告:输入一个n,让你判断(1n + 2n + 3n + 4n) mod 5的结果是多少?注意n的 ...

  7. 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 ...

  8. Codeforces - 65D - Harry Potter and the Sorting Hat - 简单搜索

    https://codeforces.com/problemset/problem/65/D 哈利波特!一种新思路的状压记忆化dfs,记得每次dfs用完要减回去.而且一定是要在dfs外部进行加减!防止 ...

  9. CF456B Fedya and Maths 找规律

    http://codeforces.com/contest/456/problem/B CF#260 div2 B Fedya and Maths Codeforces Round #260 B. F ...

随机推荐

  1. Laravel 数据库连接, 数据库名,配置文件修改

    数据库连接:在根目录(laravel5.1下面有个.env文件,如果没有则会有个.env.example然后将此文件修改成.env文件即可)打开文件:找到:DB_HOST=127.0.0.1  //连 ...

  2. HDU 2102 A计划 (BFS)

    A计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  3. Citrix_XenServer-6.1安装过程详解(转)

    本次为使用VirtualBox虚拟机过安装测试机过程,我们在使用Vm(无论是Vbox还是VMware等)我们的CPU都必须可支持Intel-V或AMD-V,并且在VM软件设置和BIOS设置开启虚拟化支 ...

  4. 网页编程-Djiango(二)

    一.初始Ajax ajax的写法: $.ajax({ url:'/host', type:'POST' data:{'k1':123,'k2':'root'} success:function(dat ...

  5. forEach for for in for of性能问题

    var arr = new Array(1000); console.time('forEach'); arr.forEach(data => { }); console.timeEnd('fo ...

  6. android studio 程序真机执行中文显示乱码

    代码里中文显示正常,真机执行后中文显示乱码,解决的方法: build.gradle中加入一句 android { compileOptions.encoding = "GBK" }

  7. Javascript学习之Date对象详解

    1.定义 创建 Date 实例用来处理日期和时间.Date 对象基于1970年1月1日世界协调时起的毫秒数 2.语法 构造函数 new Date() new Date(value) value代表自世 ...

  8. go 文件上传

    package main import ( "fmt" "io" "io/ioutil" "log" "net ...

  9. this.triggerEvent()用法

    在对组件进行封装时 在当前页面想要获取组件中的某一状态,需要使用到this.triggerEvent(' ',{},{}),第一个参数是自定义事件名称,这个名称是在页面调用组件时bind的名称,第二个 ...

  10. 基于BASYS2的VHDL程序——数字钟(改进版)

    扩展到时分秒.加了入调时电路,但不知道为什么有两个按键不好使.而且不知道以何种方式假如按键消抖电路,因为加入后会多个时钟控制一个信号,物理不可实现.调试电路待解决.还有,四个数目管中间的那两个圆点怎么 ...