CF776E 题解
Sol
打表发现 \(f(n)\) 是积性函数,且 \(g(n)=n\)。将这些代入递推式,可以发现 \(F_k(n)\) 就是 \(f(n)\) 的 \(\lceil\frac{k}{2}\rceil\) 次复合后得到的结果。
仔细观察可以发现当 \(p\) 为质数时 \(f(p^k)=(p-1)p^{k-1}\),于是我们可以 \(O(\sqrt n)\) 求出来 \(f(n)\)。
结合 \(f(1)=1\),\(f(n)<n\),我们可以每次 \(O(\sqrt n)\) 求 \(f(n)\) 一直求 \(k\) 次,中途如果 \(n=1\) 就退出,交上去发现过了。
考虑证明。
首先根据更相减损术,有 \(\gcd(i,n-i)=\gcd(n,i)\),于是 \(f(n)=\sum_{i=1}^{n-1}[\gcd(i,n)=1]\),这不是我们欧拉函数吗。
根据欧拉函数的性质,有 \(g(n)=\sum_{d\mid n}\varphi(\frac{n}{d})=\sum_{d\mid n}\varphi(d)=n\)。
那么时间复杂度是多少呢?
考虑对 \(n\) 分类讨论:
- 当 \(n\neq 1\) 为奇数:\(\varphi(n)=n\prod(\frac{p_i-1}{p_i})\),\(p_i-1\) 为偶数,那么 \(\varphi(n)\) 为偶数。
- 当 \(n\) 为偶数:那么一定有 \(\frac{n}{2}\) 个偶数与 \(n\) 不互质,\(\varphi(n)<\frac{n}{2}\)。
所以其一定在 \(O(\log n)\) 次复合后变为 \(1\)。
总时间复杂度:\(O(\sqrt n\log n)\)。
Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int> pii;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
const int N=1e6+10,T=22,INF=0x3f3f3f3f3f3f3f3f,mod=1e9+7,pmod=mod-1;
int qpow(int a,int k){
int res=1;
while(k){
if(k&1)res=res*a;
a=a*a;
k>>=1;
}
return res;
}
int f(int n){
int ans=n;
for(int i=2;i*i<=n;i++){
if(n%i==0){
ans=ans/i*(i-1);
while(n%i==0)n/=i;
}
}
if(n>1)ans=ans/n*(n-1);
return ans;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int n,k;
cin>>n>>k;
k=(k+1)/2;
while(k--&&n>1)n=f(n);
cout<<n%mod<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通