UVA-1363 约瑟夫的数论问题

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq619337301/article/details/97124411

题意:

输入正整数n和k(1<=n,k<=10^{9}),计算\sum_{i=1}^{n}k\, mod\, i

分析:

根据紫书,假设k/i的整数部分等于p,则k mod i=k-i*p。于是从i,i+1,i+2,······,j,k除以它们的商的整数部分都相同,则k除以它们的余数会是一个等差数列。

这样,可以在枚举i时把它所在的等差数列之和累加到答案中。这需要计算满足[k/j]和[k/i]=p的最大j。

当p=0时这样的j不存在,所以等差数列一直延续到序列的最后。

当p>0时j为满足k/j>=p的最大j,即j<=k/p。

注意:当i>k时k mod i = k。即i>k的部分之和为k*(n-k)。

代码:

#include<iostream>
using namespace std;
typedef long long ll; 
ll ans,n,k;
void f(){
	ll i=2,p,t,d,nn;
	ans=0;
	while(i<k){
		if(i>n)
			break;
		p=k/i;
		t=k%i;
		d=k/p;
		//printf("i:%d p:%d t:%d d:%d ",i,p,t,d);
		nn=min(d,n)-i+1;
		ans+=nn*t+((k%(i+1)-t)*(nn-1)*nn)/2;
		//printf("%d\n",(d-i+1)*t+(k%(i+1)-t)*(d-i));
		i=min(d,n)+1;
	}
	if(n>k){
		ans+=k*(n-k);
	}
}
int main(){
	while(cin>>n>>k){
		f();
		cout<<ans<<endl;
	}
	return 0;
} 

 

展开阅读全文

没有更多推荐了,返回首页