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;
}




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