1257: [CQOI2007]余数之和sum
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 1138 Solved: 509
[ Submit][ Status]
Description
给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值,其中k mod i表示k除以i的余数。例如j(5, 3)=3 mod 1 + 3 mod 2 + 3 mod 3 + 3 mod 4 + 3 mod 5=0+1+0+3+3=7
Input
输入仅一行,包含两个整数n, k。
Output
输出仅一行,即j(n, k)。
Sample Input
5 3
Sample Output
7
HINT
50%的数据满足:1<=n, k<=1000 100%的数据满足:1<=n ,k<=10^9
Source
【分析】:
求Σ(K%i),1≤i≤N
K%i=K-(K/i)*i,对于i至K/(K/i)这一段K/i相同,可以一起算,可证总段数是sqrt(N)的。
复杂度:O(Sqrt(N))
K%i=K-(K/i)*i,对于i至K/(K/i)这一段K/i相同,可以一起算,可证总段数是sqrt(N)的。
复杂度:O(Sqrt(N))
【代码】:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
#define MAXN 1000001
long long N,K,number[MAXN],tot=0;
long long ans=0;
int main()
{
//freopen("input.in","r",stdin);
//freopen("output.out","w",stdout);
scanf("%lld%lld",&N,&K);
for(int i=1;i<=(int)sqrt(K);i++)
{
number[++tot]=i;
if(K/i!=i) number[++tot]=K/i;
}
sort(number+1,number+1+tot);
long long last=(N>K?K:N);
for(int i=1;i<=tot;i++)
{
if(number[tot-i]+1<=last)
{
long long sigma_i=(number[tot-i]+1LL+last)*(last-number[tot-i])/2LL;
ans=ans-sigma_i*number[i];
last=number[tot-i];
}
}
ans+=N*K;
printf("%lld\n",ans);
//system("pause");
return 0;
}
转载注明出处:
http://blog.csdn.net/u011400953