P3327 [SDOI2015] 约数个数和

套进莫比乌斯函数随便弄一下就可以了 :

\[\begin{aligned} & \sum\limits^{n}_{i=1}\sum\limits^{m}_{j=1}\sum\limits_{x|i}\sum\limits_{y|j} [\gcd(x,y)=1] \\ = & \sum\limits^{n}_{i=1}\sum\limits^{m}_{j=1}\sum\limits_{x|i}\sum\limits_{y|j}\sum\limits_{d| \gcd(x,y)} \mu(d) \\ = & \sum\limits^{\min\{n,m\}}_{d=1} \mu(d)\sum\limits^{n}_{i=1}\sum\limits^{m}_{j=1}\sum\limits_{x|i}\sum\limits_{y|j} [d|\gcd(x,y)] \\ = & \sum\limits^{\min\{n,m\}}_{d=1} \mu(d)\sum\limits^{n}_{i=1}\sum\limits^{m}_{j=1}[d|\gcd(i,j)] \sum\limits_{x|i}\sum\limits_{y|j} 1 \\ = & \sum\limits^{\min\{n,m\}}_{d=1} \mu(d)\sum\limits^{n}_{x=1}\sum\limits^{m}_{y=1} [d|x] [d|y] \left\lfloor \frac n x \right\rfloor \left\lfloor \frac m y \right\rfloor \\ = & \sum\limits^{\min\{n,m\}}_{d=1} \mu(d)\sum\limits^{\left\lfloor \frac n d \right\rfloor}_{x=1}\sum\limits^{\left\lfloor \frac m d \right\rfloor}_{y=1} [d|xd] [d|yd] \left\lfloor \frac n {xd} \right\rfloor \left\lfloor \frac m {yd} \right\rfloor \\ = & \sum\limits^{\min\{n,m\}}_{d=1} \mu(d) \left(\sum\limits^{ \left\lfloor \frac n d \right\rfloor }_{x=1} \left\lfloor \frac n {xd} \right\rfloor \right) \left(\sum\limits^{ \left\lfloor \frac m d \right\rfloor }_{y=1} \left\lfloor \frac m {yd} \right\rfloor \right) \\ = & \sum\limits^{\min\{n,m\}}_{d=1} \mu(d) \left(\sum\limits^{ q }_{x=1} \left\lfloor \frac q x \right\rfloor \right) \left(\sum\limits^{p}_{y=1} \left\lfloor \frac p y \right\rfloor \right) [q=\left\lfloor \frac n d \right\rfloor][p=\left\lfloor \frac m d\right\rfloor ] \\\end{aligned} \]

所以说最后的公式我们可以对整除分块进行预处理 , 跑的时候再搞一次即可。预处理复杂度 \(O(n \log \log n)\) , 查询复杂度 \(O(Tn^{\frac{1}{2}})\)

手推 , 所以赘述了很多内容 , 代表个人的理解。如果全 \(\text{WA}\) , 注意看一下自己的分块预处理的边界问题。

Uses math;

Const
    total=50000+10;

var
    block,incea,mobius:array[-1..total] of int64;
    i,j,n,m,k,test:longint;
    ans:int64;

procedure Mobius_make;
var i,j:longint;
begin
    mobius[1]:=1;
    for i:=1 to total do for j:=2 to total div i+1 do begin if i*j>total then break; dec(mobius[i*j],mobius[i]); end;
    for i:=1 to total do incea[i]:=incea[i-1]+mobius[i];
end;

procedure Mathblock_make;
var i,j,k:longint;
begin
    for k:=1 to total do
    begin
        i:=1; j:=0;
        repeat j:=k div (k div i); inc(block[k],(j-i+1)*(k div i)); i:=j+1; until i>k;
    end;
end;

begin
    read(test); Mobius_make; Mathblock_make;
    for k:=1 to test do
    begin
        read(n,m); i:=1; j:=0; ans:=0;
        repeat
            j:=min(n div (n div i),m div (m div i));
            inc(ans,block[n div i]*block[m div i]*(incea[j]-incea[i-1])); i:=j+1;
        until i>min(n,m);
        writeln(ans);
    end;
end.
posted @ 2019-11-24 12:51  Rattry  阅读(90)  评论(0)    收藏  举报