bzoj 2301 莫比乌斯反演

本文提供了一个关于 Problem 2301 的详细解析及代码实现,使用 Pascal 语言进行解答,并通过筛法预处理莫比乌斯函数,然后进行区间求和,最终解决该问题。

类似于2820,贴上内个题的题解吧  

  http://www.cnblogs.com/BLADEVIL/p/3486834.html

另:强制转int64比普通int64运算快好多,本来TLE了,改了就A了。。。

/**************************************************************
    Problem: 2301
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:34964 ms
    Memory:1204 kb
****************************************************************/
 
//By BLADEVIL
var
    a, b, c, d, k, t                    :longint;
    ans                                 :int64;
    i                                   :longint;
    prime, miu, mindiv                  :array[0..50010] of longint;
    sum                                 :array[0..50010] of int64;
     
procedure make;
var
    i, j                                :longint;
begin
    miu[1]:=1;
    for i:=2 to 50000 do
    begin
        if mindiv[i]=0 then
        begin
            inc(prime[0]);
            prime[prime[0]]:=i;
            mindiv[i]:=i;
            miu[i]:=-1;
        end;
        for j:=1 to prime[0] do
        begin
            if i*prime[j]>50000 then break;
            mindiv[i*prime[j]]:=prime[j];
            if i mod prime[j]=0 then
            begin
                miu[i*prime[j]]:=0;
                break;
            end else
                miu[i*prime[j]]:=-miu[i];
        end;
    end;
    for i:=1 to 50000 do sum[i]:=sum[i-1]+miu[i];
end;
     
function calc(n,m:longint):longint;
var
    t, t1, t2                           :int64;
    i                                   :longint;
    xx                                  :int64;
begin
    calc:=0;
    i:=1;
    if n>m then xx:=m else xx:=n;
    while i<=xx do
    begin
        t1:=n div (n div i);
        t2:=m div (m div i);
        if t1<t2 then t:=t1 else t:=t2;
        calc:=calc+(sum[t]-sum[i-1])*(n div i)*(m div i);
        i:=t+1;
    end;
end;
     
begin
    make;
    readln(t);
    for i:=1 to t do
    begin
        readln(a,b,c,d,k);
        ans:=int64(calc(b div k,d div k))
            -int64(calc((c-1) div k,b div k))
            -int64(calc((a-1) div k,d div k))
            +int64(calc((a-1) div k,(c-1) div k));
        writeln(ans);
    end;
end.

 

转载于:https://www.cnblogs.com/BLADEVIL/p/3487942.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值