[2020.12.07周一]赛氪A题
题解:根据欧几里得辗转相除,很容易想到\(gcd(i,n-i)=gcd(i,n)\)
\[\begin{align*}
&当n>1,f(n)=\sum_{i=1}^{n-1}[gcd(i,n-i)==1]=\sum_{i=1}^{n-1}[gcd(i,n)==1]+[gcd(n,n)==0]=\sum_{i=1}^{n}[gcd(i,n)==1]=\varphi (n)\\
&\therefore f(n)=\varphi(n)\\
&g(n)=\sum_{d|n}f(\frac{n}{d})=\sum_{d|n}f(\frac{n}{d})·1(d)=\varphi*1=id,恒等函数\\
&\therefore g(n)=n\\
&综上,这题只要作(k+1)/2次欧拉就好了;\\
&但这个k依然很大,但没关系因为log次必然迭代到1,按照cy的说法是暴跳到1然后break;\\
&复杂度O(n\log n)\\
&下面来证明[思路by cy]:log次必然迭代到1(赛场上因为没证出来,不敢冲)\\
&根据欧拉定理,n=p_1^{k_1}p_2^{k_2}\cdots p_n^{k_n},\varphi(n)=n·\prod_{i=1}^{s} \frac{p_i-1}{p_i}\\
&\varphi(奇数)=偶数\\
&\varphi(偶数)\le偶数/2\\
&\varphi(n)\le n-1\\
&因此,\varphi(\varphi(n))\le n/2
&p.s.这个证明不严谨,因为欧拉函数没有单调性,cy想了一个办法规避它,但我还没看懂
\end{align*}
\]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
long long euler(long long n)
{
long long res=n,a=n;
for(long long i=2;i*i<=a;i++){
if(a%i==0){
res=res/i*(i-1);//先进行除法是为了防止中间数据的溢出
while(a%i==0) a/=i;
}
}
if(a>1) res=res/a*(a-1);
return res;//返回euler(n)
}
int main()
{
int T;ll n, k;
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld",&n,&k);
k=(k+1)/2;
for(int i=1;i<=k;i++){
n=euler(n);
if(n==1) break;
}
printf("%lld\n",n%mod);
}
}