bzoj1257(数学方法)

首先,floor(n/d)的所有情况最多有2*sqrt(n)种,那么列出所有情况,在一定的区间内n/i是相同的(因为相同可以一起算),并且显然他们的余数以n/d为公差

作等差数列求和,再将所有不同的n/i的值累积起来,就求出最终答案了

给出 100以内的模数

100
100%1 0
100%2 0
100%3 1
100%4 0
100%5 0
100%6 4
100%7 2
100%8 4
100%9 1
100%10 0
100%11 1
100%12 4
100%13 9
100%14 2
100%15 10
100%16 4
100%17 15
100%18 10
100%19 5
100%20 0
100%21 16
100%22 12
100%23 8
100%24 4
100%25 0
100%26 22
100%27 19
100%28 16
100%29 13
100%30 10
100%31 7
100%32 4
100%33 1
100%34 32可以很显然的发现都是以n/i为公差往下走,且n/i不变
100%35 30
100%36 28
100%37 26
100%38 24
100%39 22
100%40 20
100%41 18
100%42 16
100%43 14
100%44 12
100%45 10

100%46 8
100%47 6
100%48 4
100%49 2
100%50 0
100%51 49
100%52 48
100%53 47
100%54 46
100%55 45
100%56 44
100%57 43
100%58 42
100%59 41
100%60 40
100%61 39
100%62 38
100%63 37
100%64 36
100%65 35
100%66 34
100%67 33
100%68 32
100%69 31
100%70 30
100%71 29
100%72 28
100%73 27
100%74 26
100%75 25
100%76 24
100%77 23
100%78 22
100%79 21
100%80 20
100%81 19
100%82 18
100%83 17
100%84 16
100%85 15
100%86 14
100%87 13
100%88 12
100%89 11
100%90 10
100%91 9
100%92 8
100%93 7
100%94 6
100%95 5
100%96 4
100%97 3
100%98 2
100%99 1
100%100 0


K%i=K-(K/i)*i,对于i至K/(K/i)这一段K/i相同,可以一起算,可证总段数是sqrt(N)的。

复杂度:O(Sqrt(N))


/**************************************************************
    Problem: 1257
    User: zhhx
    Language: C++
    Result: Accepted
    Time:16 ms
    Memory:820 kb
****************************************************************/
 
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
 
ll n,k;
int main()
{
    scanf("%lld%lld",&n,&k);
    long long ans=0;
    if (n>k) ans=k*(n-k),n=k;//如果n>k那么n>k的部分的模数都是k
    ll kk=0;
    for (int i=1;i<=n;i=kk+1)
    {
        kk=min(n,i+k%i/(k/i));//推出区间后端,这块要记住,以后莫比乌斯反演时也要用
        ans+=(k%i+k%kk)*((k%i-k%kk)/(k/i)+1)/2;//等差数列求和,首项加末项*项数/2
    }
    printf("%lld",ans);
    return 0;
}


事实告诉我,一道题只要肯想,激发脑力,你就一定可以做到,你才能最终突破自己,没有这样一个激情的过程,绝不会成为强者!!

那是思维的历练,唯有如此,你才能达到成功的彼岸!! 只有完全确定自己想不出来时,才能看题解,要有绝对的思维过程

要知道,你要用你的绝对意志力支撑起思维的堡垒,在真正没有思路前,绝不放弃。

没有这样的思维锻炼,是无法突破自己的,赵和旭,你要加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值