首页 > 代码库 > NYOJ 508 余数求和 (数论问题)
NYOJ 508 余数求和 (数论问题)
题目描述
http://acm.nyist.net/JudgeOnline/problem.php?pid=508
给你两个数n,k,请求出的值。
- 输入
- 每行两个数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<n res=ModSum(k)+(n-k)*k;注:当n>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<iostream> #include<cstdio> #include<map> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<vector> #include<stack> #include<cstdlib> #include<cctype> #include<cstring> #include<cmath> #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/(i+1)<<" "<<n/i<<endl; LL tt=n*(n/i-(n/(i+1)))-i*((n/i+(n/(i+1))+1)*(n/i-(n/(i+1)))/2); //sum=(sum+(tt%MOD*i%MOD)%MOD)%MOD; sum=(sum+tt); } //cout<<n1<<k<<endl; if(k<=n1){ sum+=(n1-k)*k; } else { for(LL i=n1+1;i<=k;i++){ sum-=k%i; } } return sum; } int main() { long long n,k; while(cin>>n>>k){ //LL sum1=ModSum1(n); LL sum2; sum2=ModSum2(n,k); cout<<sum2<<endl; } return 0; }
NYOJ 508 余数求和 (数论问题)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。