UVALive 7340 Sum of MSLCM

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5362


题意:求2~n每个数的因子和的和。


思路:我们可以发现i加了n/i次。而且次数的个数很少,比如加1次的就有(n+1)/2个。所以我们就枚举次数,二分上下界。每次将同次数的数求和累加答案。


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;

#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)
#define Clean(x,y) memset(x,y,sizeof(x))
#define LL long long

int n;
int main()
{
    while( scanf("%d",&n) == 1 )
    {
        if ( !n ) break;
        LL ans = n-1; //1出现了n-1次
        LL st = n-(n+1)/2+1;
        ans += (LL)(n+1)/2*( st + n )/2; //单独计算次数为1的答案即后(n+1)/2个数求和
        int t = n/2;
        int L = 2 , R = n;//当前上下界
        int m;
        while( t!= 1 ) //如果次数为1,那么已经全部统计完了
        {
            int l = L;
            int r = R;
            while( l < r ) //二分当前次数的上下界
            {
                m = ( l + r ) >> 1;
                if ( n / (m+1) >= t )
                    l = m + 1;
                else r = m;
            }
            ans += (LL)t * (r-L+1)*(L+r)/2; //次数 * (范围内数的和)
            L = l + 1; //更新边界和下一个次数
            t = n / L;
        }
        printf("%lld\n",ans);
    }
    return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章