设为首页 加入收藏

TOP

NYOJ 508 余数求和 (数论问题)
2015-07-20 17:25:17 来源: 作者: 【 】 浏览:3
Tags:NYOJ 508 余数 求和 数论 问题

题目描述

?

给你两个数n,k,请求出border=0的值。

输入每行两个数n, k(1 <= n, k <= 10^9).输出输出和,每个结果占一行。样例输入
5 4
5 3
样例输出
5
7

题目分析:

对于此题不能直接进行暴力,数值大,只能用sqrt(n)的算法,首先计算n%i的余数和,i=1~n;注意到:n%i=n/i*i;

因此我们可以模拟从i=1~sqrt(n);sum+=n%i;对于i对应的j=n/i,可以知道(n/i~n/i+1)==d;对与这组数,计算得到

s1=((n/i-n/(i+1))*n)-d*(n/(i+1)+1+......+n/i);sum+=s1;直到循环结束,就得到n%i的余数和,我们用ModSum(n)。

现在我们求k%i的余数和,i=1~n;进行分析k和n即可,

一、k k时,k%n==k

二、k=n res=ModSum(k)

三、k>n res=ModSum(k); { for(int i=n+1;i<=n;i++)

res-=k%i;//减去多计算的值即可。

}

?

AC代码:

?

 
/**
 *1、ModSum1():O(n)
 *2、ModSum2():O(sqrt(n))
 *1   2   3   4
 *16  8   5   4
 *  1   2   3
 */
#include
    
     
#include
     
       #include
       #include
       
         #include
        
          #include
         
           #include
          
            #include
           
             #include
            
              #include
             
               #include
              
                #include
               
                 #include
                
                  #define LL long long #define MOD 1000000007 using namespace std; LL ModSum1(LL n){ LL t=(n+1)/2-1; LL sum=t*(t+1)/2; for(LL i=1;i<=n/2;i++){ sum+=n-(n/i*i); } return sum; } LL ModSum2(LL n,LL k){ LL sum=0,n1=n; n=k; LL tem=sqrt(n); for(LL i=1;i<=tem;i++){ if(n/i==i){ sum+=n-n/i*i; continue; } sum+=n-n/i*i; sum=sum; //cout<
                 
                  >n>>k){ //LL sum1=ModSum1(n); LL sum2; sum2=ModSum2(n,k); cout<
                  
                   

?

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇NYOJ 285 寻找克隆人(map+计数) 下一篇NYOJ 1057 寻找最大数(三) (贪..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C 内存管理 | 菜鸟教 (2025-12-26 20:20:37)
·如何在 C 语言函数中 (2025-12-26 20:20:34)
·国际音标 [ç] (2025-12-26 20:20:31)
·微服务 Spring Boot (2025-12-26 18:20:10)
·如何调整 Redis 内存 (2025-12-26 18:20:07)