CC's

Back

技巧#

自然溢出#

  • 自然溢出不会影响低位数据,所以有的时候你不需要取模,而是一个unsigned.

除法取模#

对于式子

a×bcmodpa×bmodcpc\frac {a \times b}{c} \mod p \equiv \frac{a \times b \mod cp}{c}

细节#

  • 注意数据类型,例如6*(ll)(1<<30)是要出问题的
  • 注意函数在f(1)f(1)位置的取值,不要忘记初始化

单点ϕ\phi的求解#

ll euler_phi(ll n) {
    ll m = sqrt(n + 0.5);
    ll ans = n;
    for (ll i = 2; i <= m; i++)
        if (n % i == 0) {
            ans = ans / i * (i - 1);
            while (n % i == 0) n /= i;
        }
    if (n > 1) ans = ans / n * (n - 1);
    return ans;
}
cpp

Divisor#

Given nn and mm (1n,m5×1041 \leq n,m \leq 5 \times 10^4), please calculate

分析#

下面所有的除法都是舍去小数的整除.

i=1nj=1mσ0(ij)=i=1nj=1mpiqj[pq]=i=1nj=1mpiqjd(p,q)μ(d)=i=1nj=1mpiqjdμ(d)[dp][dq]=dμ(d)i=1nj=1mpdqd[pdi][qdj]=dμ(d)pdqdi=1n/pdj=1m/qd=dμ(d)pdqdnpdmqd=dμ(d)pn/dnpdqm/dmqd\begin{aligned} \sum_{i=1}^n\sum_{j=1}^m \sigma_0(ij) &= \sum_{i=1}^n\sum_{j=1}^m \sum_{p|i}\sum_{q|j}[p \perp q] \\ &=\sum_{i=1}^n\sum_{j=1}^m \sum_{p|i}\sum_{q|j}\sum_{d|(p,q)}\mu(d) \\ &=\sum_{i=1}^n\sum_{j=1}^m \sum_{p|i}\sum_{q|j}\sum_{d}\mu(d)[d|p][d|q] \\ &=\sum_d \mu(d)\sum_{i=1}^n\sum_{j=1}^m \sum_{pd} \sum_{qd}[pd|i][qd|j] \\ &=\sum_d \mu(d) \sum_{pd} \sum_{qd}\sum_{i=1}^{n/pd}\sum_{j=1}^{m/qd} \\ &=\sum_d \mu(d) \sum_{pd} \sum_{qd} \frac n {pd}\frac m {qd} \\ &=\sum_d \mu(d) \sum_p^{n/d} \frac n {pd} \sum_q^{m/d} \frac m {qd} \\ \end{aligned}

S(n)=1inniS(n)=\sum_{1\leq i \leq n} \frac n i

i=1nj=1mσ0(ij)=dμ(d)S(n/d)S(m/d)\begin{aligned} \sum_{i=1}^n\sum_{j=1}^m \sigma_0(ij) &=\sum_d \mu(d)S(n/d)S(m/d) \end{aligned}

n/dn/d的取值在一个区间中是相同的,因此可以把这个求和公式分块计算.(在分块后,需要获知该段区域内μ\mu的和,所以需要求前缀和)由于n/dn/d的取值为O(n)O(\sqrt n)的级别,因此在知道SS的值的情况下,每个询问可以这个复杂度中计算出来.

对于μ\mu,使用筛法,并求出其前缀和.

对于SS,直接暴力计算.

代码#

table#

给出多组n,m,an,m,a,求

i=1nj=1mσ1((i,j))[σ1((i,j))a]\sum_{i=1}^n \sum_{j=1}^m \sigma_1((i,j))[\sigma_1((i,j)) \geq a]

分析#

这道题让谁都能看出来重点是如何处理条件

[σ1((i,j))a][\sigma_1((i,j)) \geq a]

可是这我显然不知道该怎么做.

对询问作以aa从小到大离线处理,询问前先处理新增aa的影响.

在已经满足条件的前提下对公式作化简.

i=1nj=1mσ1((i,j))=di=1nj=1mσ1(d)[(i,j)=d]=dindjmdσ1(d)[(i,j)=1]=dintdjmtdσ1(d)tμ(t)=dtμ(t)σ1(d)intdjmtd1=TnTmTdTμ(t)σ1(Td)\begin{aligned} \sum_{i=1}^n \sum_{j=1}^m \sigma_1((i,j)) &= \sum_d \sum_{i=1}^n \sum_{j=1}^m \sigma_1(d)[(i,j)=d] \\ &=\sum_d \sum_{i\leq \frac nd}\sum_{j\leq \frac md}\sigma_1(d)[(i,j)=1] \\ &=\sum_d \sum_{i\leq \frac n{td}}\sum_{j\leq \frac m{td}}\sigma_1(d) \sum_t \mu(t) \\ &=\sum_d \sum_t \mu(t) \sigma_1(d) \sum_{i\leq \frac n{td}}\sum_{j\leq \frac m{td}} 1 \\ &=\sum_T \lfloor \frac nT \rfloor \lfloor \frac mT \rfloor \sum_{d|T}\mu(t)\sigma_1(\frac Td) \end{aligned}

可以看到还是套路,引入d,引入μ\mu,之后胡乱化简.

按照这个式子,需要计算的就是g(x)=dTμ(t)σ1(Td)g(x)=\sum_{d|T}\mu(t)\sigma_1(\frac Td)的前缀和.

接下来是如何处理条件…

aa每扩大一点,就有一部分μ(t)σ1(Td)\mu(t)\sigma_1(\frac Td)被加入到函数gg的各个部分.使用一种数据结构来维护gg的前缀和,例如树状数组.aa最大到,每次受到影响的就是dd的倍数,以此可以计算出总的时间复杂度为

WTFWTF

至此,问题就解决了.

代码#

又丑又长.

product#

定义斐波纳妾(?)(linux这输入法够魔性)函数f(x)f(x)

i=1nj=1mf((i,j))\prod_{i=1}^n \prod_{j=1}^m f((i,j))

分析#

首先,先引个dd是没错了.

但是

这道题,我又不会.我不知道该怎么处理\prod…蔡就完事了.

现在来看,当引入一个dd后,在该求积公式里出现了相同项相乘.将该部分的计算调整为幂,剩下的就又都一样了.

i=1nj=1mf((i,j))=df(d)injm[(i,j)=d]=df(d)indjmd[(i,j)=1]=df(d)tμ(t)intdjmtd1=dtf(d)μ(t)intdjmtd1=T(dTf(d)μ(Tt))nTmT\begin{aligned} \prod_{i=1}^n \prod_{j=1}^m f((i,j)) &= \prod_d f(d)^{\sum_{i\leq n} \sum_{j \leq m} [(i,j)=d]} \\ &=\prod_d f(d)^{\sum_{i\leq \frac nd} \sum_{j \leq \frac md} [(i,j)=1]} \\ &=\prod_d f(d)^{\sum_t \mu(t) \sum_{i\leq \frac n{td}} \sum_{j \leq \frac m{td}} 1 } \\ &=\prod_d \prod_t f(d)^{\mu(t) \sum_{i\leq \frac n{td}} \sum_{j \leq \frac m{td}} 1 } \\ &=\prod_T (\prod_{d|T} f(d)^{\mu(\frac Tt)})^{\lfloor \frac nT \rfloor \lfloor \frac mT \rfloor } \end{aligned}

g(x)=dTf(d)μ(Tt)g(x)=\prod_{d|T} f(d)^{\mu(\frac Tt)},求前缀和就完事了.

这道题需要使用欧拉定理来优化求幂的速度.

欧拉定理#

(a,p)=1(a,p)=1,有以下式子

ababmodϕ(p)(modp)a^b \equiv a^{b \mod \phi(p)} \pmod p

(a,p)1(a,p)\neq 1,有扩展欧拉定理

ababmodϕ(p)+ϕ(p)(modp)a^b \equiv a^{b \mod \phi(p)+ \phi(p)} \pmod p

根据这2个式子,可以在快速降幂,来加快运算.

代码#

phi3#

给出nn,求

(i=1nj=1nk=1nϕ(i)ϕ(j2)ϕ(k3)ϕ(i)ϕ(j)ϕ(k)ϕ((i,j,k)))mod230(\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^n \frac {\phi(i)\phi(j^2)\phi(k^3)}{\phi(i)\phi(j)\phi(k)} \phi((i,j,k))) \mod 2^{30}

分析#

这道题重点在于

ϕ(i)ϕ(j2)ϕ(k3)ϕ(i)ϕ(j)ϕ(k)\frac {\phi(i)\phi(j^2)\phi(k^3)}{\phi(i)\phi(j)\phi(k)}

这堆东西的化简.很显然,我又不会.

观察ϕ(n)\phi(n)的公式

ϕ(n)=ni(11ϕ(i))\phi(n)=n\prod_i(1-\frac 1{\phi(i)})

可以得出上面那一堆等于jk2jk^2.剩下的就又都一样了.

i=1nj=1nk=1njk2ϕ((i,j,k))=di=1nj=1nk=1njk2ϕ(d)[(i,j,k)=d]=dtϕ(d)μ(t)t3d3intdjntdkntdjk2=TinTjnTjknTk2(T3dTϕ(d)μ(Td))\begin{aligned} \sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^n jk^2 \phi((i,j,k)) &=\sum_d\sum_{i=1}^n\sum_{j=1}^n\sum_{k=1}^n jk^2 \phi(d)[(i,j,k)=d] \\ &=\sum_d \sum_{t} \phi(d) \mu(t) t^3d^3 \sum_{i\leq \frac n{td}}\sum_{j \leq \frac n{td}}\sum_{k \leq \frac n{td}} jk^2 \\ &=\sum_T \sum_{i\leq \frac nT}\sum_{j \leq \frac nT} j\sum_{k \leq \frac nT}k^2 (T^3 \sum_{d|T} \phi(d) \mu(\frac Td)) \end{aligned}

g(n)=dTϕ(d)μ(Td)g(n)=\sum_{d|T} \phi(d) \mu(\frac Td),直接筛.最后计算前缀和的时候再乘上n3n^3就可以了.

这道题的取模还有这种处理方法: 直接取数组为unsigned并自然溢出.二进制后30位不会受到影响.

代码#

一些筛法的题
https://astro-pure.js.org/blog/some-sieve
Author Cheng Chen
Published at 2019年9月5日
Comment seems to stuck. Try to refresh?✨