bzoj 2956 数学展开,分段处理

首先对于答案

ΣΣ(n mod i)*(m mod j) i<>j

也就是Σ(n mod i)Σ(m mod j)-Σ(n mod i)(m mod i)

将mod展开,我们可以得到有floor的式子,对于这种式子,我们可以

利用分段的思想,将O(N)的简化为sqrt(n)的

/**************************************************************
    Problem: 2956
    User: BLADEVIL
    Language: Pascal
    Result: Accepted
    Time:388 ms
    Memory:224 kb
****************************************************************/
 
//By BLADEVIL
const
    d39                             =19940417;
     
var
    n, m                            :int64;
    ans, ans2                       :int64;
 
function min(a,b:int64):int64;
begin
    if a>b then min:=b else min:=a;
end;
     
function calc(x,y:int64):int64;
var
    i, j                            :int64;
    z                               :int64;
begin
    calc:=0;
    i:=1;
    while i<=y do
    begin
        j:=x div (x div i);
        if j>y then j:=y;
        z:=((i+j)*(j-i+1) div 2) mod d39;
        calc:=(calc+(z*(x div i) mod d39) mod d39)mod d39;
        i:=j+1;
    end;
end;
 
function sum(x:int64):int64;
var
    a, b, c                         :int64;
begin
    if x=0 then exit(0);
    a:=x; b:=x+1; c:=2*x+1;
    if a mod 3=0 then a:=a div 3 else
    if b mod 3=0 then b:=b div 3 else
    if c mod 3=0 then c:=c div 3;
    if a mod 2=0 then a:=a div 2 else
    if b mod 2=0 then b:=b div 2 else
    if c mod 2=0 then c:=c div 2;
    sum:=a mod d39;
    sum:=sum*b mod d39;
    sum:=sum*c mod d39;
end;
 
 
function fuck:int64;
var
    i, j                            :int64;
    t1, t2                          :int64;
    z                               :int64;
begin
    i:=1;
    fuck:=0;
    while i<=min(n,m) do
    begin
        t1:=n div (n div i);
        t2:=m div (m div i);
        j:=min(t1,t2);
        z:=(((sum(j)-sum(i-1)) mod d39+d39) mod d39);
        z:=(z*(n div i)) mod d39;
        z:=(z*(m div i)) mod d39;
        fuck:=(fuck+z) mod d39;
        i:=j+1;
    end;
end;
 
begin
    read(n,m);
    ans2:=calc(m,m) mod d39;
    ans2:=((m*m-ans2) mod d39+d39) mod d39;
    ans:=((n*n-calc(n,n)) mod d39*ans2) mod d39;
    ans2:=(n*m mod d39)*min(n,m) mod d39;
    ans2:=(ans2+fuck) mod d39;
    ans2:=((ans2-m*calc(n,min(n,m)))mod d39+d39) mod d39;
    ans2:=((ans2-n*calc(m,min(n,m)))mod d39+d39) mod d39;
    ans:=((ans-ans2) mod d39+d39) mod d39;
    writeln(ans);
end.

 

posted on 2013-12-25 21:02  BLADEVIL  阅读(298)  评论(0编辑  收藏  举报