题解 UVA11526 【H(n)】

Link

upd2021.7.23:对某些地方进行修改。

题意

long long H(int n){
    long long res=0;
    for( int i = 1; i <= n; i=i+1 ){
        res = (res + n/i);
    }
    return res;
}

的值。

多组数据。

1T103,1n<231

思路

很明显,直接模拟题目给出的函数会 TLE。

我们理解一下题目给的代码,其实就是求i=1nni

此时,我们需要引入算法:整除分块(又称数论分块、除法分块)。此算法可以快速求出形如i=1nf(ni) 的式子,在数论题目中有着广泛的用途。

对于一些情况,一段数满足nl=nl+1=nl+2=...=nl+m=...=nr1=nr 这时候我们把这个值重复地加了几遍,浪费了时间。

我们可由向下取整的性质得:

nlnr<nl+1

化简得

rnnl

rmax=nnl

所以对于上面这 rl+1 个相同的数它们的和为(nnll+1)×nl

分析一下时间复杂度,发现时间复杂度即对于 n,所有的 ni 的取值数量,可以知道,ni 可以取得 1,2,,n,nn,nn1,,nO(n) 种取值,即时间复杂度为 O(Tn)

注意此题轻微卡常。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){

}
inline int h(int n){
    if(!n){
        return 0;
    }
    int res=0,j;
    for(register int i=1;i<=n;i=j+1){
        j=n/(n/i);
        res+=(j-i+1)*(n/i);
    }
    return res;
}
signed main(){
    int t,n;
    t=read();
    while(t--){
        n=read();
        printf("%lld\n",h(n));
    }
    return 0;
}

再见 qwq~

posted @   ffffyc  阅读(14)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示