zoukankan      html  css  js  c++  java
  • BZOJ 1257

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1257

    题意:

    给定正整数 $n,k$,求 $(k mod 1) + (k mod 2) + cdots + (k mod n) = sum_{i=1}^{n}(k mod i)$ 的值。

    题解:

    显然 $k mod i = k - lfloor k/i floor imes i$,因此 $sum_{i=1}^{n}(k mod i) = sum_{i=1}^{n}(k - lfloor k/i floor imes i) = n cdot k - sum_{i=1}^{n}(lfloor k/i floor imes i)$。

    对于任意正整数 $x in [1,k]$, 设 $g(x) = lfloor frac{k}{lfloor k/x floor} floor$,不难得出 $lfloor k/x floor le k/x Rightarrow frac{k}{lfloor k/x floor} ge frac{k}{k/x} Rightarrow lfloor frac{k}{lfloor k/x floor} floor ge lfloor frac{k}{k/x} floor$,即 $g(x) ge lfloor frac{k}{k/x} floor = lfloor x floor = x$。

    又根据 $f(x) = frac{k}{x}$ 是一个单调递减函数,得到

    $f(g(x)) le f(x) Rightarrow frac{k}{g(x)} le frac{k}{x} Rightarrow lfloor frac{k}{g(x)} floor le lfloor frac{k}{x} floor$

    另一方面,根据 $g(x) le frac{k}{lfloor k/x floor}$ 还能得出

    因此,综上可以得出 $lfloor frac{k}{g(x)} floor = lfloor frac{k}{x} floor$;也就是说,对于任意的正整数 $i in [x,g(x)]$,$lfloor frac{k}{i} floor$ 都是相等的。

    而与此同时,对于任意的正整数 $i in [1,k]$,$lfloor frac{k}{i} floor$ 的值最多只有 $2 sqrt{k}$ 个,这是因为:

    当 $i le sqrt{k}$ 时,$i$ 最多只有 $sqrt{k}$ 个选择,相对应地,$lfloor frac{k}{i} floor$ 也就最多 $sqrt{k}$ 个值;而当 $i > sqrt{k}$ 时,$lfloor frac{k}{i} floor le frac{k}{i} < sqrt{k}$,即 $lfloor frac{k}{i} floor$ 只能取 $1 sim sqrt{k}$ 之间的值。

    所以,对于任意的正整数 $i in [1,k]$,$lfloor frac{k}{i} floor$ 的值划分成 $O(sqrt{k})$ 段。每一段上 $i in [x,g(x)]$,$lfloor frac{k}{i} floor$ 的值都等于 $lfloor frac{k}{x} floor$。而在这一段中,$sum_{i=x}^{g(x)}(lfloor k/i floor imes i) = lfloor k/x floor sum_{i=x}^{g(x)}i$,即一个等差数列的求和。因此这个算法时间复杂度为 $O(sqrt{k})$。

    AC代码:

    /**************************************************************
        Problem: 1257
        User: Dilthey
        Language: C++
        Result: Accepted
        Time:20 ms
        Memory:1288 kb
    ****************************************************************/
     
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
     
    ll n,k,ans;
    inline ll g(ll x){return k/(k/x);}
    inline ll sum(ll L,ll R){return (L+R)*(R-L+1)/2;}
    int main()
    {
        while(cin>>n>>k)
        {
            ll ans=n*k;
            n=min(n,k);
            for(ll x=1;x<=n;x=g(x)+1)
            {
                ll y=min(g(x),n);
                ans-=(k/x)*sum(x,y);
            }
            cout<<ans<<endl;
        }
    }
  • 相关阅读:
    Event notifications
    twobin博客样式
    Http协议
    ASP.NET Web API自身对CORS的支持: CORS授权检验的实施
    理解计算机系统3
    游标-Oracle游标汇总
    Oracle10g 回收站及彻底删除table : drop table xx purge
    ora-01031:insufficient privileges
    &&运算符和||运算符的优先级问题 专题
    oracle connect by 和start with
  • 原文地址:https://www.cnblogs.com/dilthey/p/10700252.html
Copyright © 2011-2022 走看看