zoukankan      html  css  js  c++  java
  • 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.
  • 相关阅读:
    bash shell学习shell基础 (笔记)
    Linux入门 (笔记)
    《Effective C++》 阅读小结 (笔记)
    趣味PAT循环19. 币值转换(20)
    git学习小结 (笔记)
    一个新手Java编程的初次感受
    201671010112 第四周的感悟
    201671010112 老同学的java学习之路
    全民IT时代到来了?学计算机很有前途?——淘宝2011校园招聘笔试感想
    编写友好的命令行应用程序
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3491362.html
Copyright © 2011-2022 走看看