当前位置: 首页 > news >正文

整除分块 (+例题变形K-取模 2022年天梯赛(GPLT)上海理工大学校内选拔赛)

文章目录

  • 整除分块
      • 题意
      • 思路
      • 代码

整除分块

K-取模 2022年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛

这本是一道取模的题目,运用数学公式转换,便可以用整除分块解决。


先介绍一下整除分块

以20为例,一共出现了多少个i的倍数?

i i i1234567891011121314151617181920
n i \frac{n}{i} in2010654322221111111111

可以发现在连续的一段区间内是相同的,那么就启发我们是否可以将其分为若干块分别进行计算呢?

这就是整除分块的核心思想了。

n/i 表示n里面出现了几个 i 的倍数。
也就是在n个里面,每i个为一组,可以分n/i 组,每组里有一个i的倍数

当然会有剩余的。

如果再用 n 除以 n/i ,便是如果分为 n/i 组,那么每组应该有 n/(n/i) =x 个
注意:每次都是向下取整

即x个数字为一组,会有 n/i组(当然也有剩余),也就是这x个都至少有 n/i个倍数

那么区间【i,x】,倍数皆为 n/i

总结:

利用除法的性质,将问题分解为若干个块,每个块内的值相同,从而减少计算量。整除分块在解决一些数学问题时非常有效,特别是当问题涉及到大量除法操作时,它可以大大减少计算时间。

题意

计算 ∑ i = 1 n ( n % i ) \sum_{i=1}^{n}{(n\%i)} i=1n(n%i)

因为答案可能很大,因此只需要输出答案需要对998244353取模后的结果

思路

赛时一直从规律入手,打表,废了太长时间。应该从变化数学公式、整除分块入手。

且看以下推导(懒得用latex):

请添加图片描述

代码

void solve()
{
    int n,ans=0;
    cin>>n;
    ans=(n%mod)*(n%mod)%mod;//n^2
    __int128 i=1,j=1;//区间和会超longlong,int128最大值最高位2^127-1,不会溢出
    while(i<=n)
    {
        j=min ((__int128)n,n/(n/i));
        ans=(ans-((i+j)*(j-i+1)/2%mod*((n/i)%mod)%mod)+mod)%mod;//多取模
        i=j+1;
    }
    cout<<ans<<'\n';
}

感谢亓boyan的整除分块启蒙

相关文章:

  • 最长公共子序列(动态规划法+优化)
  • NL2SQL 优化之 Schema 编写标准
  • 单词翻转(信息学奥赛一本通-1144)
  • AI视觉测试工具实战评测:以Applitools为例的技术解析与行业应用
  • CoreData 调试警告:多个 NSEntityDescriptions 声明冲突的解决
  • JSON 数据详解
  • 【再读】R1-Onevision通过跨模态形式化为复杂多模态推理任务提供了系统性解决方案
  • 盘库吧--搜索
  • 开源模型中的 Function Call 方案深度剖析
  • 【Linux系统】进程地址空间详解
  • 代码随想录算法训练营第五十九天| 图论05
  • 【MySQL】MySQL如何存储数据?
  • 计算机网络-1-1计算机网络体系结构
  • 清晰易懂的Java8安装教程
  • Deepseek API+Python测试用例一键生成与导出-V1.0.2【实现需求文档图片识别与用例生成自动化】
  • 可视化图解算法:判断链表中是否有环(环形链表)
  • JVM 垃圾回收器分类及其特点详解
  • TypeScript语言的计算机视觉
  • 前端性能优化回答思路
  • 【自学笔记】Redis基础知识点总览-持续更新
  • 人民日报和音:相信中国就是相信明天
  • 俄外长与美国务卿通电话,讨论俄美接触等问题
  • 江西4人拟任县(市、区)委书记,其中一人为“80后”
  • 病愈出院、跳大神消灾也办酒,新华每日电讯:农村滥办酒席何时休
  • 霍步刚任辽宁沈阳市委书记
  • 受贿1.29亿余元,黑龙江省原副省长王一新被判无期