bzoj 2301 莫比乌斯反演

类似于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.

 

你可能感兴趣的:(ZOJ)