Description
在一次偶然的情况下,小可可得到了一个密码箱,听说里面藏着一份古代流传下来的藏宝图,只要能破解密码就能打开箱子,而箱子背面刻着的古代图标,就是对密码的提示。经过艰苦的破译,小可可发现,这些图标表示一个数以及这个数 与密码的关系。假设这个数是n,密码为x,那么可以得到如下表述:密码x大于等于0,且小于n,而x的平方除以n,得到的余数为1。 小可可知道满足上述条件的x可能不止一个,所以一定要把所有满足条件的x计算出来,密码肯定就在其中。计算的过程是很艰苦的,你能否编写一个程序来帮助小可可呢?(题中x, n均为正整数)
输入文件只有一行,且只有一个数字 n(1≤n≤2×109) \
Output
你的程序需要找到所有满足前面所描述条件的x,如果不存在这样的x,你的程序只需输出一行“None”(引号不输出),否则请按照从小到大的顺序输出这些x,每行一个数。
思路
显然想让我们求的是这个式子:
x2≡1 (mod n)
稍加思索,可以得到这个形式:
x2−1≡0 (mod n)(x+1)(x−1)≡0 (mod n)
设 n=a∗b ,
则 a∗b|(x+1)(x−1) ,即 a|x+1,b|x−1 或 a|x−1,b|x+1 。
设 a<b ,枚举 a ,然后枚举 x=kb+1 或 x=kb−1 ,a 枚举到 √n 即可
时间复杂度 O(√n∗√n)=O(n)
此题水炸了,不想写(尤其是考试的时候,脑子也不知道在想什么,最后才看出来)
思路
我看到这题的第一想法:用 f(n)=(p1+1)(p2+1)...(pk+1) 求出每个数,然后觉得 n 有点大,就放弃了
考虑每个因子在式子中的贡献,可知2这个因子出现了 ⌊n2⌋ 次,3这个因子出现了 ⌊n3⌋ 次,以此类推,可知 pi 的贡献是 ⌊npi⌋ ,则答案为 ⌊n2⌋+⌊n3⌋+...+⌊npi⌋+... 。
可以选择把 N 以下的 ⌊npi⌋ 预处理出来
C.BZOJ2142 礼物
Description
一年一度的圣诞节快要来到了。每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物。不同的人物在小E心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多。小E从商店中购买了n件礼物,打算送给m个人,其中送给第i个人礼物数量为wi。请你帮忙计算出送礼物的方案数(两个方案被认为是不同的,当且仅当存在某个人在这两种方案中收到的礼物不同)。由于方案数可能会很大,你只需要输出模P后的结果。
输入的第一行包含一个正整数P,表示模;第二行包含两个整整数n和m,分别表示小E从商店购买的礼物数和接受礼物的人数;以下m行每行仅包含一个正整数wi,表示小E要送给第i个人的礼物数量。
Output
若不存在可行方案,则输出“Impossible”,否则输出一个整数,表示模P后的方案数。
HINT
设 p=pc11∗pc22∗pc33∗...∗pctt,pi 为质数。
对于100%的数据,1≤n≤109,1≤m≤5,1≤pcii≤105。
思路
exLucas:干 他 就 完 了
按照正常的思路,可列出组合数相乘的式子:
Cw1n∗Cw2n−w1∗...∗Cwmn−m−1∑i=1wi (mod p)
但是我们知道,这样暴力算肯定是不行(可行的,并且是正解(╯▔皿▔)╯,下面不想看的就不看了)的,所以将 Cmn 展开,即:
Cmn=n!m!(n−m)!
不难发现,原式中的前一项的分母和后一项的分子是可以相消的。可将原式化简为:
n!w1!∗w2!∗...∗wm!∗(n−m∑i=1wi)! (mod p)
然后预处理出阶乘的逆元,但是因为友(e)善(du)的出题人明确说明 p 不一定是质数,所以求逆元需要分开,亿点点求,即求出每个 n!%pckk
(下面是我之前的总结)
-
如何求 n!%pkii
我们以 n=19,pi=3,ki=2 为例
n!=1∗2∗3∗4∗5∗6∗7∗8∗9∗10∗11∗12∗13∗14∗15∗16∗17∗18∗19=(1∗2∗4∗5∗7∗8∗10∗11∗13∗14∗16∗17∗19)∗36∗(1∗2∗3∗4∗5∗6)
根据这个例子发现,求解n!可以分为3部分:第一部分是 pi的幂的部分,也就是 36即 p⌊npi⌋i,可以直接求解;第二部分是一个新的阶乘,也就是6!即 ⌊npi⌋!,可以递归下去求解;第三部分是除前两部分之外剩下的数
-
考虑第三部分如何求解
发现第三部分在模 pkii 意义下是以 pkii 为周期的,即:
(1∗2∗4∗5∗7∗8)≡(10∗11∗13∗14∗16∗17) (mod pkii) ,所以只要求出 pkii 的长度即可;
但是还剩下一个孤立的19,可以发现剩下孤立的数长度不会超过 pkii ,只需要暴力求解即可
-
最后一个问题是对于求出的 m!%pkii 和 (n−m)!%pkii 有可能与 pkii 不互质,无法求逆元
所以要将 (n−m)!%pkii 和 m!%pkii 中质因子 pi 先全部除去,求出逆元后再全部乘回去
计算n!中质因子p的个数x的公式为 x=⌊np⌋+⌊np2⌋+⌊np3⌋+...
递推式也可以
写为 f(n)=f(⌊np⌋)+⌊np⌋
Update:2020.7.25.10:06 : 因为 m≤5 所以直接暴力好像更快(
Update:2020.7.25.9:12 :果然,正解是直接 ex Lucas 定理 ヽ(*。>Д<)o
(特判:当 m∑i=1wi>n 时,无解)
思路
三角形数量=在平面上随便找仨点-三点共线情况
在平面上随便找仨点 =C3(n+1)(m+1)
三点共线有三种情况:横着,竖着,斜着
横着,竖着 =(n+1)C3m+1+(m+1)C3n+1
主要是斜着的比较难搞,有斜率上升和下降两种。不难发现两种数量相等,所以我们设 ans 为上升的数量,最后乘二即可
设 AB 为长度为 i 的竖着的一条线段, BC 为长度为 j 的横着的一条线段
画图可以看出,AC 上的点数为 gcd(i,j)+1 (不加顶点为 gcd(i,j)−1 )
则像 A,B 这样横坐标差 j ,纵坐标差 i 的点对共有 (n−i+1)(m−j+1)
枚举 i,j 可得
ans=n∑i=1m∑j=1(n−i+1)(m−j+1)(gcd(i,j)−1)
此时直接枚举是 O(nm)=O(n2) ,考虑 gcd 的计算的话可能会达到 O(n2logn) 。
优化复杂度
通过欧拉反演可以将 [gcd(i,j)=1] 化为 ∑d|gcd(i,j)φ(d) 。(原理:∑d|nφ(d)=n 下面证明)
则,原式转化为:
ans=n∑i=1m∑j=1(n−i+1)(m−j+1)⎛⎝∑d|gcd(i,j)φ(d)−1⎞⎠
因为 φ(1)=1 ,所以可以微微转化一下:
ans=n∑i=1m∑j=1(n−i+1)(m−j+1)d≠1∑d|gcd(i,j)φ(d)
接下来,我们看看 d|gcd(i,j) 的含义:
i,j 的最大公因子的每个因子 。
也就是 i,j 的每个公约数
枚举 i,j 再枚举他们的所有公约数,等价于枚举每个约数 d 再枚举 d 的 i 倍、j 倍。
那 d 的取值范围可化为 [2,min(n,m)] , i,j 最小取 1 ,最大取 ⌊dn⌋,⌊dm⌋ ,即:
ans=min(n,m)∑d=2⌊n/d⌋∑i=1⌊m/d⌋∑j=1(n−id+1)(m−jd+1)φ(d)=min(n,m)∑d=2φ(d)⌊n/d⌋∑i=1(n−id+1)⌊m/d⌋∑j=1(m−jd+1)
很明显(这我开始也不明显),⌊n/d⌋∑i=1(n−id+1) 是等差数列求和,
首项为 n−d+1 ,末项是 n−⌊nd⌋d+1 即 n mod d+1 ,项数是 ⌊nd⌋ ,由通项公式得:
⌊n/d⌋∑i=1(n−id+1)=12(n−d+1+n mod d+1)⌊nd⌋
同理有:
⌊m/d⌋∑i=1(n−id+1)=12(m−d+1+m mod d+1)⌊md⌋
最后得到:
ans=14min(n,m)∑d=2φ(d)(n−d+n mod d+2)⌊nd⌋(m−d+m mod d+2)⌊md⌋
欧拉函数用欧拉筛线性预处理出来,枚举 d 复杂度 O(min(n,m))=O(n)
∑d|nφ(d)=n 证明(会的可以跳过)
我们首先看这么几个数
1n,2n,3n,...nn
如果要化成 ab 这样的最简分数的形式,要满足两个条件:
1.b|n 2.gcd(a,b)=1
,显然对于每个 b,共有 φ(b) 个,而 n 的约数共有 ∑d|n 个,那么可得:
∑d|nφ(d)=n
那个的严格证明我忘了,嘻嘻嘻
下面的题有了
E.BZOJ4173 数学
题目
懒得放了。。。。
思路
通过题目,我们可以设 m=q1∗k+r1,n=q2∗k+r2 ,则题目中的式子可化为 r1+r2≥k ,所以 ⌊m+nk⌋=q1+q2+1 ,则 m+nk−nk−mk=1
那么 ∑k∈S(n,m)φ(k) 可化为 m+n∑k=1φ(k)[m+nk−nk−mk=1],即:
m+n∑k=1φ(k)⌊m+nk⌋−n∑k=1φ(k)⌊nk⌋−m∑k=1φ(k)⌊mk⌋
我们设 F(n)=n∑k=1φ(k)⌊nk⌋
则可化为 F(n+m)−F(n)−F(m) ,单独考虑 F(n) :
通过 ∑d|nφ(d)=n ,可将 F(n) 转化为:
n∑k=1φ(k)⌊nk⌋=n∑i=1∑k|iφ(k)=n∑i=1i
所以,上式化为:
m+n∑i=1i−m∑i=1i−n∑i=1i
这显然等差数列求和,于是:
(1+m+n)(m+n)2−m(m+1)2−n(n+1)2=mn
所以,φ(m)∗φ(n)∗∑k∈S(n,m)φ(k) 就等于:
φ(n)∗φ(m)∗nm
然后用欧拉筛或者别的办法求 φ 即可
因为直接求 φ 时间复杂度是 O(√n) 的,所以总时间复杂度为 O(n)
∑d|nφ(d)=n 的小证明
设 n=m∏i=1paii ,
由于欧拉函数是积性函数,则有:
∑d|nφ(d)=∑m∏i=1φ(p ji) (0≤j≤ai)
因式分解,上式等价于:
m∏i=1(ai∑j=0φ(p ji))=m∏i=1(ai∑j=1(p ji−p j−1i)+1)=m∏i=1paii=n
(有的是放了题,有的只写了思路,(●'◡'●))
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】