整除分块笔记
大概题意:有
Solution
你看它函数都给出来了,直接抄不好吗
TLE狂喜
众所周知,这题要用分块
正如标题,这题可以看作分块模板
何为分块?
以此题为例,当
可以看出
而题目给的解法会重复计算这些重复出现的数字
所以这是我们要利用分块的思想来减少计算量
比如此题中
还是以
我们从
此时我们已经确定了结果为
观察
当结果为
所以我们可以求得最后一个结果为
但是我们也不能枚举肯定会寄
但是我们已经求出了上一个值的的右界
众所周知,左界
所以
代码
1#define ll long long //偷懒小技巧
2inline ll f(ll n){ //inline 可以更快
3 ll sum=0;
4 for(ll l=1,r;l<=n;l=r+1){ //左界
5 //开long long避免炸精度
6 r = n / (n / l); //右界
7 sum += (r - l + 1) * (n / l);
8 }
9 return sum;
10}
代码还是自己写有效果,抄一遍也比复制好
双倍经验1
P2261 [CQOI2007]余数求和
温馨提示:这题和上一题几乎一样,就是多了一些细节上的处理。
参考代码:
点我点我
#include<bits/stdc++.h>
using namespace std;
int main(){
long long n, k;
cin>>n>>k;
long long cnt=n*k;
for(long long l=1, r; l<=n; l=r+1){
if (k/l!=0) r=min((k/(k/l)), n);
else r=n;
cnt-=(r+l)*(k/l)*(r-l+1)/2;
}
cout<<cnt;
}
学习整除时,写了一道题,写完后打开题解突然发现第一篇和上文代码一样。
经过仔细的思考,我发现了其中的联系。 真相只有一个
在
你品,你细品
双倍经验2
P2424 约数和
温馨提示:这题也只是多了一些细节。
实在想不出再来点我欧~
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll f(ll n){
if(n<=1) return n;
ll res=0;
for(ll l=1,r;l<=n;l=r+1){
r = n / (n / l);
res += (r - l + 1) * (n / l) * (l + r) / 2;
}
return res;
}
int main(){
ll x,y;
scanf("%lld%lld", &x, &y);
printf("%lld\n", f(y)-f(x-1));
}
Update
2022.9.24:增加 P2424 约数和 和 [AHOI2005]约数研究。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】