1 条题解
-
0
自动搬运
来自洛谷,原作者为

whiteqwq
寻找着梦与现实的交点 在哪呢 在哪呢搬运于
2025-08-24 22:05:23,当前版本为作者最后更新于2021-03-22 13:41:33,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
P4930 [PA2013]Euler解题报告:
题意
组数据,给定,求的所有。()
分析
原来的题目数据有锅,修完数据后拿到了首杀。
搜索题。
首先求出的所有因子计入,然后把所有中为质数的值存入,不难发现和很小,随便
交几发讨论一下就可以知道最大是,最大是。记为数字在质因数中的排名,但由于这里可能存不下,因此考虑对于的大小讨论:如果则将的排名存入,否则将的排名存入,这样就只需要开的数组了。
然后就开始玄学起来了。
设代表中第一个是因子的数的编号,(如果不存在则为)
这里介绍一个众所周知的结论:对于,满足(下面有证明)。
然后进行搜索:表示现在搜索到第个了,将除到了(这个为值),并把答案乘到了,边界就是的时候直接把放入答案。
不难发现一定在里(可以通过和找到),因此我们可以通过跳过那些不能整除的。
然后再分类讨论就好了:
- 与当前质数无关系,直接。
- 只有次幂,把除去,把乘上,然后。
- 有高次幂,那么在次幂的基础上将除去若干次,把乘上若干次,然后。
复杂度很玄学,但跑的很稳。
代码
记得特判,还有有些地方需要排序。
#include<stdio.h> #include<algorithm> #define int long long using namespace std; const int maxn=1000005,maxm=2505,maxk=700; int T,n,cnt,m,Ps,Ds,anss; int p[maxn],a[maxn],P[maxk],D[maxm],ans[maxn],ord[maxn],nord[maxn],f[maxm][maxk]; void sieve(int n){ for(int i=2;i<=n;i++){ if(p[i]==0) a[++cnt]=i; for(int j=1;j<=cnt;j++){ if(i*a[j]>n) break; p[i*a[j]]=1; if(i%a[j]==0) break; } } } int check(int x){ if(x<=1000000) return p[x]==0; for(int i=2;i*i<=x;i++) if(x%i==0) return 0; return 1; } void dfs(int pos,int val,int now){ if(now==1){ ans[++anss]=val; return ; } if(now<=m) pos=f[ord[now]][pos]; else pos=f[nord[n/now]][pos]; if(pos==Ps+1) return ; dfs(pos+1,val,now); val*=P[pos],now/=P[pos]-1,dfs(pos+1,val,now); while(now%P[pos]==0) val*=P[pos],now/=P[pos],dfs(pos+1,val,now); } signed main(){ scanf("%lld",&T),sieve(1000000); while(T--){ scanf("%lld",&n); if(n==1){ puts("2\n1 2"); continue; } for(m=1;1ll*(m+1)*(m+1)<=n;m++); for(int i=1;i<=m;i++) if(n%i==0){ D[++Ds]=i; if(check(i+1)) P[++Ps]=i+1; if(1ll*i*i!=n){ D[++Ds]=n/i; if(check(n/i+1)) P[++Ps]=n/i+1; } } sort(P+1,P+1+Ps),sort(D+1,D+1+Ds); for(int i=1;i<=Ds;i++){ if(D[i]<=m) ord[D[i]]=i; else nord[n/D[i]]=i; f[i][Ps+1]=Ps+1; for(int j=Ps;j>=0;j--) f[i][j]=D[i]%(P[j]-1)==0? j:f[i][j+1]; } dfs(1,1,n),sort(ans+1,ans+1+anss); printf("%lld\n",anss); for(int i=1;i<=anss;i++) printf("%lld%c",ans[i],i==anss? '\n':' '); if(anss==0) puts(""); for(int i=1;i<=Ds;i++){ if(D[i]<=m) ord[D[i]]=0; else nord[n/D[i]]=0; } anss=Ds=Ps=0; } return 0; }证明
这里有一份时代久远的关于上面式子的证明:
$$\begin{bmatrix} 1&2&\cdots&m\\ m+1&m+2&\cdots&2m\\ \vdots&\vdots&&\vdots\\ (n-1)m+1&(n-1)m+2&\cdots&nm \end{bmatrix} $$引理:欧拉函数的积性 构造一个()的矩阵:
易知每一行都是m的完全剩余系,那么对于所有,都有。 因此有$\forall_{1\leqslant i\leqslant n}\left\{a_{i,1},a_{i,2},\cdots,a_{i,m}\right\}\in\left\{km,km+1,km+2,\cdots,(k+1)m-1\right\}(k\in\mathbb{N})$。 也很容易证明每一列都是的完全剩余系。 反证法:设与模同余,且,那么。 也就是$(i_1-1)\times m+j=k_1\times n+r,(i_2-1)\times m+j=k_2\times n+r$。 两式相减得。 又因为,所以那么不难发现,所以每一列都是的完全剩余系。 由欧拉函数的定义得矩阵内可以找到列,其中有个元素同时与m和n互素,即共个元素与和互素,也就是与互素。
然后证明欧拉函数的公式:对于,满足。
首先很显然为质数的时候,。
然后是时(为质数,):
很容易证明,与等价,那么可以发现与不互素的数只有这个数。
那么$\varphi(n)=n-p^{k-1}=p^k\times\frac{p-1}{p}=n\times\frac{p-1}{p}$。
当为任意正整数时,设,由的积性可知$n=\prod_{i=1}^s \varphi(p_i^{k_i})=\prod_{i=1}^s(p^{k_i}\times\frac{p-1}{p})=n\times\prod_{i=1}^s\frac{p_{i-1}}{p_i}$。
- 1
信息
- ID
- 5057
- 时间
- 2000ms
- 内存
- 128MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者