码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 数论-整除分块


    好久没碰数论的东西了,已经完全生疏了。

    做了几道数论题总结一下。

    余数求和

    大意:
    求 \sum_{i=1}^{n}k%i

    思路:
    隐约记得哪次比赛做过原题,也做出来了,但是现在还是有点懵了。。。

    先把式子转化一下吧

    \sum_{i=1}^{n}k%i= \sum_{i=1}^{n}k-\left \lfloor k/i \right \rfloor\doteq n*k-\sum_{i=1}^{n}i*\left \lfloor k/i \right \rfloor

    那么整个式子就稍微有点样子了。

    接下来对每一个l求对应的r

    令t=\left \lfloor k/l \right \rfloor,

    r=max(i),i*t<=n;

    得到:

    r=k/t;

    这是对于每一个l对应的r,对于\sum里面的i*\left \lfloor k/i \right \rfloor,i在连续的区间里是一个等差数列,那么直接套公式即可。

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. #define ll long long
    4. #define mx *max_element
    5. const ll N=2e5+10;
    6. ll n,k,r;
    7. int main()
    8. {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    9. cin>>n>>k;
    10. ll ans=n*k;
    11. for(int l=1;l<=n;l=r+1)
    12. {
    13. ll t=k/l;
    14. if(t!=0) r=min(k/t,n);
    15. else r=n;
    16. ans-=t*(r-l+1)*(l+r)/2;
    17. }
    18. cout<<ans<<endl;
    19. return 0;
    20. }

    虽然是一道省选-,但代码是真的短。

    calculating

    大意:

    思路:
    首先,这个\prod_{i=1}^{n}ki就是求\sigma (n),也就是我们所熟知的求数字约数的函数,换句话说,这里f(x)=\sum_{i=1}^{n}\sum_{d|i}^{}1,其中\sum_{d|i}1=\sigma (i).

    不妨做一个转换,改为先枚举d,则

    f(x)=\sum_{i=1}^{n}\sum_{d|i}^{}1=\sum_{d=1}^{n}\left \lfloor n/d \right \rfloor,

    到这一步,要求f(x)那就是轻而易举了。

    最后,由于i是从l到r,那么\sum_{i=l}^{r}f(x)=\sum_{i=1}^{r}f(x)-\sum_{i=1}^{l-1}f(x),这样的话写一个函数就好了。

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. #define ll long long
    4. const ll mod=998244353;
    5. ll a,b;
    6. ll f(ll x)
    7. {
    8. ll ans=0;
    9. ll l,r;
    10. for(ll l=1;l<=x;l=r+1)
    11. {
    12. r=x/(x/l);
    13. ans=(ans+(x/l)*(r-l+1)%mod)%mod;
    14. }
    15. return ans%mod;
    16. }
    17. int main()
    18. {
    19. cin>>a>>b;
    20. cout<<(f(b)-f(a-1)+mod)%mod<<endl;
    21. return 0;
    22. }

    点是有点多,但都想到了就挺板的。

    模积和

    大意:

    思路:
    这里有一个限制是i!=j,所以不妨把式子转化一下。

    \sum_{i=1}^{n}\sum_{j=1}^{m}n%i*m%j(i\neq j)=\sum_{i=1}^{n}\sum_{j=1}^{m}(n%i)*(m%j)-\sum_{i=1}^{n}(n%i)*(m%i)

     其中\sum_{i=1}^{n}\sum_{j=1}^{m}(n%i)*(m%j)=\sum_{i=1}^{n}n%i*\sum_{j=1}^{m}m%j

    这个就是我们在第一个问题里讨论的东西,那应该就很好处理了。

    然后是后面的东西,如果展开的话:

    \sum_{i=1}^{n}(n%i)*(m%i)=\sum_{i=1}^{n}(n-i*\left \lfloor n/i \right \rfloor)*(m-i*\left \lfloor m/i \right \rfloor)

    =\sum_{i=1}^{n}n*m-m*i*\left \lfloor n/i \right \rfloor-n*i*\left \lfloor m/i \right \rfloor+i*i*\left \lfloor n/i \right \rfloor*\left \lfloor m/i \right \rfloor

    这里的第一项就不用说了,第二三项其实跟上面讨论的\sum_{i=1}^{n}n%i=\sum_{i=1}^{n}n-i*\left \lfloor n/i \right \rfloor是一个道理,只是加了一个常数而已。

    那么最后一项,i*i*\left \lfloor n/i \right \rfloor*\left \lfloor m/i \right \rfloor,与上一个的区别只是i的次数提高了一项,但如果照搬之前的思路,求等差数列的和的话,\sum i^{^{2}}=n*(n+1)*(2n+1)/6,那么这一项也解决了,那么整个题目到这里也就ok了。

    还想说一个坑点,就是题目里这个取模的数居然不是质数。。。

    也怪我傻,998244353,1e9+7见多了,看啥都像质数

    所以这里的逆元得自己提前去求好了,不能用快速幂。

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. #define ll long long
    4. const ll mod=19940417;
    5. const ll inv2=9970209;
    6. const ll inv6=3323403;
    7. #define endl '\n'
    8. ll n,m;
    9. ll sd(ll x)
    10. {
    11. return x*(x+1)%mod*(2*x+1)%mod*inv6%mod;
    12. }
    13. ll sdd(ll x)
    14. {
    15. return x*(x+1)%mod*inv2%mod;
    16. }
    17. ll f(ll n)//求sum(n-(n/i)*i)
    18. {
    19. ll sum=n*n%mod;
    20. //cout<<sum<<endl;
    21. for(ll l=1,r;l<=n;l=r+1)
    22. {
    23. ll t=n/l;
    24. r=n/t;
    25. sum=(sum-t*(sdd(r)-sdd(l-1)+mod)%mod+mod)%mod;
    26. //cout<<sum<<endl;
    27. }
    28. return sum;
    29. }
    30. int main()
    31. {
    32. cin>>n>>m;
    33. //cout<<sdd(4)<<' '<<sdd(3)<<endl;
    34. //cout<<f(n)<<" "<<f(m)<<endl;
    35. ll sum=0,ans=0;
    36. sum=(sum+f(n))%mod;
    37. sum=(sum*f(m))%mod;
    38. ans=sum;sum=0;
    39. for(ll l=1,r;l<=min(n,m);l=r+1)
    40. {
    41. r=min(n/(n/l),m/(m/l));
    42. sum+=(r-l+1+mod)%mod*n%mod*m%mod;
    43. sum-=(r-l+1+mod)%mod*(l+r)%mod*((n/l)*m%mod+(m/l)*n%mod)%mod*inv2%mod;
    44. sum+=(sd(r)-sd(l-1)+mod)%mod*(n/l)%mod*(m/l)%mod;
    45. sum=(sum+mod)%mod;
    46. }
    47. cout<<(ans-sum+mod)%mod<<endl;
    48. return 0;
    49. }

    大致就先这样,后面可能会补新的题 

  • 相关阅读:
    MATLAB小技巧(21)矩阵分析--偏最小二乘回归
    详解【计算机类&面试真题】军队文职考试——第7期:C盘格式化需要注意什么?| 两台笔记本连起来后ping不同,可能存在哪些问题?| 模拟信号到数字信号是如何转化的?| 计算机由哪些部件组成?
    【Transformer系列】深入浅出理解ViT(Vision Transformer)网络模型
    33、matlab矩阵分解汇总:LU矩阵分解、Cholesky分解、QR分解和SVD分解
    获取真实IP总结
    【自动驾驶】开源仿真环境及项目资料汇总(持续更新)
    [N0wayback 2023春节红包题] happyGame python反编译
    OAuth2:搭建授权服务器
    数据隐私与链上交易如何双赢?首周 Web3 开发者集结精彩回顾
    单细胞+RIP-seq项目文章| Cell Reports&hnRNPU蛋白在小鼠精原干细胞池建立的关键作用
  • 原文地址:https://blog.csdn.net/sophilex/article/details/125510519
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号