成都电子神技大学模拟题(取模运算)
题目描述
给出正整数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
输入
第一行2个数n,k。
输出
一个数 j(n,k)。
样例
Input |
Output |
5 3 |
7
|
50% 数据 满足 n<1e6
100%数据 满足 n<1e12 k<=n
开始毫无头绪可言,直接2分钟写了50%的ZZ代码。。。。
怎么找规律?打表:
100/100=1……0
100/99=1……1
100/98=1……2
100/97=1……3
100/96=1……4
100/95=1……5
100/94=1……6
100/93=1……7
100/92=1……8
100/91=1……9
100/90=1……10
100/89=1……11
100/88=1……12
100/87=1……13
100/86=1……14
100/85=1……15
100/84=1……16
100/83=1……17
100/82=1……18
100/81=1……19
100/80=1……20
100/79=1……21
100/78=1……22
100/77=1……23
100/76=1……24
100/75=1……25
100/74=1……26
100/73=1……27
100/72=1……28
100/71=1……29
100/70=1……30
100/69=1……31
100/68=1……32
100/67=1……33
100/66=1……34
100/65=1……35
100/64=1……36
100/63=1……37
100/62=1……38
100/61=1……39
100/60=1……40
100/59=1……41
100/58=1……42
100/57=1……43
100/56=1……44
100/55=1……45
100/54=1……46
100/53=1……47
100/52=1……48
100/51=1……49
100/50=2……0
100/49=2……2
100/48=2……4
100/47=2……6
100/46=2……8
100/45=2……10
100/44=2……12
100/43=2……14
100/42=2……16
100/41=2……18
100/40=2……20
100/39=2……22
100/38=2……24
100/37=2……26
100/36=2……28
100/35=2……30
100/34=2……32
100/33=3……1
100/32=3……4
100/31=3……7
100/30=3……10
100/29=3……13
100/28=3……16
100/27=3……19
100/26=3……22
100/25=4……0
100/24=4……4
100/23=4……8
100/22=4……12
100/21=4……16
…………………………
可以看出一些规律来:
1.在除的过程中,有一段整除相等的区间,它们的余数也是成等差数列排列的,且公差就是公共商!!。
2.怎么加?ans先赋值成n*k,每次找到区间后减去整除数*i即可。
3.n>k怎么办?当i循环到大于k时,余数都为k,商都为0——将n赋值为k
4.然后想清楚后就是一个超短代码~\(≧▽≦)/~啦啦啦
代码:
#include<cstdio>
#include<iostream>
using namespace std;
long long sum;
int main()
{
freopen("C.in","r",stdin);
freopen("C.out","w",stdout);
long long n,k;
cin>>n>>k;
sum=n*k;
if(n>k)
n=k;
long long left=0,right=0,cha=0;
for(long long i=1;i<=n;i=right+1)
{
cha=k/i;left=k/(cha+1)+1;right=k/cha;//left也可以直接赋值成i。为什么?区间连续性
if(right>n)right=n;
sum-=(right+left)*(right-left+1)*cha/2;
}
cout<<sum;
return 0;
}
上天的节奏~