在做数论题时,往往需要进行和式变换,然后变换成我们可以处理的和式,再针对和式做筛法、整除分块等操作。
本文将介绍一些常见的和式变换技术。
以下出现的概念大部分为个人总结,未必是学术界/竞赛界的统一说法,有不严谨的地方请谅解。
? 作者:Eriktse
? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?
? 原文链接(阅读原文获得更好阅读体验):https://www.eriktse.com/algorithm/1101.html
和式一般有两种:区间枚举型和整除枚举型。
我们的前缀和就是一个典型的区间枚举型和式。
假设我们有一个定义域为\(x\in[1, n],x\in Z^+\)的函数\(f(x)\),那么我们可以设一个前缀和函数\(F(x)\),定义为:
求和符号中,如果没有特殊说明,一般枚举的都是整数,且步长为1。
约数个数是一个典型的整除枚举型和式,我们可以容易的写出它的表达式:
其中 \(d|n\) 表示 \(i\) 可以整除 \(n\) ,即 \(i\) 是 \(n\) 的因子。
约数之和也是一个整除枚举型和式,表达式如下:
第一种拆分如下:
这是显然的,但是基本上用不着。
第二种拆分如下:
这也是显然的。
当我们的和式里面乘上了一个常数\(k\),那么这个常数是可以提出来的,由于我们讨论的数域是整数域,这个\(k\)一般为整数。(其实对于实数也是满足条件的)。
就比如上面那个约数之和的函数:
我们知道\(d\)的取值一定在\([1, n]\),所以我们可以转换枚举类型,此时枚举指标的范围就要改变,同时加上一个布尔函数来限定。
我们称枚举的东西为“指标”,例如上面和式中
d|n中的d,i=1中的i。
给定一个整数\(k\),对于下面这种和式,我们可以把指标进行转换。
现在令\(i = i'k,j=j'k\),为什么会这么想呢?因为我们后面的布尔函数中要求\(i, j\)都包含因子\(k\),如果枚举的\(i, j\)不是\(k\)的倍数的时候这个式子是没有贡献的。
所以我们可以不一个个枚举\(i, j\),变为枚举\(k\)的倍数。我们进行整体的代换:
然后变换枚举范围和布尔函数,注意这里\(i\)的起点本应该是\(\lfloor\frac{1}{k}\rfloor\),但是\(0\)是没有讨论意义的所以我们从\(1\)开始。
现在我们可以发现后面这个布尔函数就变成了一个常见的积性函数\(\epsilon\),接下来就可以通过公式\(\mu * I = \epsilon\)进行莫比乌斯反演(其中符号\(*\)表示狄利克雷卷积)。
上式进行莫比乌斯反演后可以得到如下的和式(如果不懂莫比乌斯反演可以暂时先不管,之后再学),设\(m=\lfloor\frac{n}{k}\rfloor\)。
我们可以发现\(d|gcd(i, j)\)这个条件等价于\([d|i][d|j]\),即\(d\)同时是\(i\)和\(j\)的因子。
接下来我们进行一次枚举类型的转换:
接下来我们将\(d\)的求和符号从后面换到前面去,因为在\(\mu(d)\)中没有包含\(i, j\)的内容,可以直接换,这里需要自己理解一下。
上式转换完成后,我们可以发现后面两坨是可以进行整除分块的。
怎么理解呢?这个式子表达的就是当\(d\)确定了,在区间[1, n]中有多少整数是\(d\)的倍数,显然是\(\lfloor\frac{m}{d}\rfloor\)个。
那么和式就可转换为:
luogu P2257 YY的GCD:https://www.luogu.com.cn/problem/P2257
阅读题意我们可以知道题目所求为,不妨设\(n\le m\):
接下来开始变换:
莫比乌斯反演:
注意这里\(n\le m\),接着变换。
后面两坨可以进行整除分块,同时换一下\(p\)的枚举类型:
令\(T=pd\),交换求和次序。
再交换求和次序:
现在发现\(p\)后面那一块,可以通过类似欧拉筛的方法进行预处理。
我们设一个函数:
那么\(F(T)\)的含义就是对于\(T\)的每一个质因子\(p\),将它的\(\mu(\frac{T}{p})\)加到自身上。
做完了。
Code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e7 + 9;
int sum[N], mu[N];
void init(int n = N - 2)
{
bitset<N> vis;
vector<int> prim;
vis[1] = true;
mu[1] = 1;
for(int i = 2;i <= n; ++ i)
{
if(!vis[i])prim.push_back(i), mu[i] = -1;
for(int j = 0;j < prim.size() and i * prim[j] <= n; ++ j)
{
vis[i * prim[j]] = true;
if(i % prim[j] == 0)break;//此时i * prim[j]含有平方因子
mu[i * prim[j]] = -mu[i];//此时i * prim[j]的本质不同质因子+1,或已经含有平方因子
}
}
for(int i = 0;i < prim.size(); ++ i)
{
for(int j = 1; prim[i] * j <= n; ++ j)
{
sum[prim[i] * j] += mu[j];
}
}
for(int i = 1;i <= n; ++ i)sum[i] += sum[i - 1];
}
void solve()
{
int n, m;scanf("%lld %lld", &n, &m);
if(n > m)swap(n, m);
int ans = 0;
for(int l = 1, r;l <= n; l = r + 1)
{
r = min(n / (n / l), m / (m / l));
ans += (sum[r] - sum[l - 1]) * (n / l) * (m / l);
}
printf("%lld\n", ans);
}
signed main()
{
init();
int _;scanf("%lld", &_);
while(_ --)solve();
return 0;
}
? 本文由eriktse原创,创作不易,如果对您有帮助,欢迎小伙伴们点赞?、收藏⭐、留言?
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
随着ruby被引入为新的编程救世主,我想知道是否有人基于易用性、运行所需的资源、可用性和易定制性而有偏好。两者有更好的吗? 最佳答案 好吧,任何基于Rails的社交网络应用程序的比较都应该包括insoshi(http://portal.insoshi.com/)。话虽这么说,这三个都非常相似,区别在于实现细节。Lovd和Insoshi都是完整的Rails应用程序;它旨在供您将它们用作入门工具包,并使用您自己的自定义功能对其进行扩展。另一方面,CommunityEngine是一个Rails插件。这意味着您可以更轻松地向现有Rail
我刚刚看到whitehouse.gov正在使用drupal作为CMS和门户技术。drupal的优点之一似乎是很容易添加插件,而且编程最少,即重新发明轮子最少。这实际上正是Ruby-on-Rails的DRY理念。所以:drupal的缺点是什么?Rails或其他基于Ruby的技术有哪些不符合whitehouse.org(或其他CMS门户)门户技术的资格? 最佳答案 Whatarethedrawbacksofdrupal?对于Ruby和Rails,这确实是一个相当主观的问题。Drupal是一个可靠的内容管理选项,非常适合面向社区的站点。它
我有一个字符串变量,它只能包含6个不同的值。我想检查它是否包含前4个值之一或2个第二值之一。有没有比这更优雅的方式:ifstring.eql?'val1'||string.eql?'val2'||string.eql?'val3'||string.eql?'val4'...elsifstring.eql?'val5'||string.eql?'val6'...end可能类似于ifstringisin['val1','val2','val3','val4']? 最佳答案 您可以使用include?:if['val1','val2','
1.问题描述使用Python的turtle(海龟绘图)模块提供的函数绘制直线。2.问题分析一幅复杂的图形通常都可以由点、直线、三角形、矩形、平行四边形、圆、椭圆和圆弧等基本图形组成。其中的三角形、矩形、平行四边形又可以由直线组成,而直线又是由两个点确定的。我们使用Python的turtle模块所提供的函数来绘制直线。在使用之前我们先介绍一下turtle模块的相关知识点。turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。面向对象的接口类如下:1)TurtleScreen类:定义图形窗口作为绘图海龟的运动场。它的构造器需要一个tkinter.Canvas或ScrolledCanva
当音乐碰上区块链技术,会擦出怎样的火花?或许周杰伦已经给了我们答案。8月29日下午,B站独家首发周杰伦限定珍藏Demo独家访谈VCR,周杰伦在VCR里分享了《晴天》《青花瓷》《搁浅》《爱在西元前》四首经典歌曲Demo背后的创作故事,并首次公布18年前未发布的神秘作品《纽约地铁》的Demo。在VCR中,方文山和杰威尔音乐提及到“多亏了区块链技术,现在我们可以将这些Demos,变成独一无二具有收藏价值的艺术品,这些Demos可以在薄盒(国内数藏平台)上听到。”如何将音乐与区块链技术相结合,薄盒方面称:“薄盒作为区块链技术服务方,打破传统对于区块链技术只能作为数字收藏的理解。聚焦于区块链技术赋能,在
我有一个正在开发的命令行Ruby应用程序,我想允许它的用户提供将在部分过程中作为过滤器运行的代码。基本上,应用程序是这样做的:读入一些数据如果指定了过滤器,则使用它来过滤数据处理数据我希望过滤过程(第2步)尽可能灵活。我的想法是,用户可以提供一个Ruby文件,该文件设置一个已知常量以指向实现我定义的接口(interface)的对象,例如:#user'sfilterclassMyFilterdefdo_filter(array_to_filter)filtered_array=Array.new#domyfilteringonarray_to_filterfiltered_arrayen
我感到有点困惑——大约24小时以来,我一直在考虑在我的项目中使用哪种组播技术。基本上,我需要的是:创建组(通过一些后端进程)任意客户端广播消息(1:N,N:N)(可能)直接消息(1:1)(重要)使用我自己的后端(例如,通过某种HTTPAPI)对客户端进行身份验证/授权能够通过后端进程(或服务器插件)踢出特定的客户端这是我要的:Ruby或Haxe中的后端相关流程JS+Haxe(Flash9)中的前端—在浏览器中,因此理想情况下通过80/443进行通信,但不一定。因此,这项技术必须能够在HaxeforFlash中轻松访问,最好是Ruby。我一直在考虑:RabbitMQ(或OpenAMQ)、