一道找规律的题

题目描述

给出正整数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

5 3

Output

7

限制

50% 数据 满足 n<1e6
100%数据 满足 n<1e12 k<=n

这道就是找规律,没什么多说的,为什么放上来呢?因为这个题找到规律也不是特别好算,总之,是一道乱搞的题。

我们先来打一个表 k=100的表

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
100/20=5……0
100/19=5……5
100/18=5……10
100/17=5……15
100/16=6……4
100/15=6……10
100/14=7……2
100/13=7……9
100/12=8……4
100/11=9……1
100/10=10……0
100/9=11……1
100/8=12……4
100/7=14……2
100/6=16……4
100/5=20……0
100/4=25……0
100/3=33……1
100/2=50……0
100/1=100……0

这个表的规律非常好找到,我们的题就是求最后一列数的和,就是一堆等差数列,然后再乱搞一下就出来了,还有就是ll邪教。

我这个就不多说了,直接放代码。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<stack>
#define INF 2100000000
#define ll long long

using namespace std;

ll n,k,ans,b;

void get_queue_sum(ll start,ll end,ll d)
{
    ll num=(end-start)/d+1;
    ans+=(start+end)*num/2;
}

int main()
{
    freopen("C.in","r",stdin);
    freopen("C.out","w",stdout);
    cin>>n>>k;
    ans=(n-k)*k;
    ll j=1,pos=k-1;
    while(pos!=1)
    {
        ll s=k%pos;
        if(b)
        {
            ans+=s;
            pos--;
            continue;
        }
        ll e=(k/(j+1)-s)/j*j+s;
        if(s==e)b=1;
        if(k%(j+1)==0)e-=j;
        get_queue_sum(s,e,j);
        j++;
        pos=k/j;
    }
    cout<<ans;
    return 0;
}

大概就是这个样子,如果有什么问题,或错误,请在评论区提出,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值