整除分块(数论) 余数和

数论-整除分块

【题意】
给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值。
例如j(5, 3)=3 mod 1 + 3 mod 2 + 3 mod 3 + 3 mod 4 + 3 mod 5=0+1+0+3+3=7。

【输入格式】
输入仅一行,包含两个整数n, k。

【输出格式】
输出仅一行,即j(n, k)。

【数据范围】
1≤n,k≤10^9
【输入样例】
5 3

【输出样例】
7

 

整除分块:

       此题目中,k mod i等效于k-floor(k/i)*i;(floor代表向下取整)。所以这个题可以化为求k*n-floor(k/i)*i;就是求floor(k/i)*i的和。

       可惜的时,数据量太大,O(n)不都可以,会发现,有一些floor(k/i)是相同的。

例如17/7==17/6=2。接下来判断相同的区间即可。对于一个商floor后例如2,分母最大可以到floor(k/2)。如果是k/2+1,那么k/(k/2+1)=2*k/(k+2)=2-(4/(k+2))<2,floor后是1。

       当然,这一切讨论分母都是从1递增谈起。

核心代码:(记录商为floor(k/l)的个数)

       ll l = 1,r;

       for(l = 1;l <= n;l = r+1){

              if(k/l == 0)     break;

              r = min(k/(k/l),n);

              num[k/l]= *(r-l+1);

       }

代码:

#include<algorithm>

#include<iostream>

#include<cstring>

#include<string>

#include<cstdlib>

#include<map>

#include<cmath>

#include<vector>

#include<cstdio>



using namespace std;

typedef long long ll;

ll n,k;

int main(){

       cin >> n >> k;

       ll ans = n*k;

       ll l = 1,r;

       for(l = 1;l <= n;l = r+1){

              if(k/l == 0)     break;

              r = min(k/(k/l),n);

              ans -= ((k/l)*(l+r)*(r-l+1)/2);

       }

       cout << ans << endl;

       return 0;

}

 

求1-n中所有的因子个数。

N <=1e6;

暴力显然不行,寻求O(n)复杂度的思路。

有容斥原理的一些思想知道,对于一个n,那么是i的倍数的个数有n/i,也就是这n/i个数中都含有i因子。

       可以这样想,把n从头开始,每隔i就截断(最后不足i的话就舍掉,毕竟会floor掉)。这样分成了几段,每一个段的末尾是这个段唯一一个可以整除i的点,也就是含有因子i的元素。

代码:

#include<iostream>

#include<algorithm>



using namespace std;

typedef long long ll;

int main(){

       ll n;

       cin >> n;

       ll ans = 0;

       for(int i = 1;i <= n;i++)

              ans += (n/i);

       cout << ans << endl;

       return 0;

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值