题意:
现在给出下列两个定义: f(x)=f0(x)=∑k=0x(−1)k22x−2kC2x−k+1k,fn(x)=f(fn−1(x))(n≥1) φ(n)为欧拉函数。指的是不超过n的与n互质的正整数个数。 对于每组数据,GTW有两个正整数n,x,现在他想知道函数φ(fn(x))的值。
其实就是喊我们先去找这个函数的规律,然后再带入欧拉函数就可以咯。
但是我没有找到规律,本来我是想乱猜的。但是放弃了。
官方证明:
由打表找规律可得,∑k=0x(−1)k22x−2kC2x−k+1k=x+1,所以显然fn(x)=n+x+1,因此直接求φ(n+x+1)。时间效率O(T√n)
严格证明:
设an=∑k=0n(−1)k22n−2kC2n−k+1k
an=22n+∑k=1n(−1)k22n−2k(C2n−kk+C2n−kk−1)=∑k=0n(−1)k22n−2kC2n−kk+∑k=0n−1(−1)k+122(n−1)−2kC2(n−1)−k+1k
设bn=∑k=0n(−1)k22n−2kC2n−kk,则bn=an+an−1
bn=22n+∑k=1n−1(−1)k22n−2k(C2n−k−1k+C2n−k−1k−1)+(−1)n
=4∑k=0n−1(−1)k22(n−1)−2kC2(n−1)−k+1k+∑k=0n−1(−1)k+122(n−1)−2kC2(n−1)−kk
=4an−bn−1
得an−an−1=an−1−an−2。因为a0=1,a1=1,所以an=n+1
证明比较费时,打表找规律能很快的得出解,所以本题的关键在于打表找规律。
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
long long f(long long n)
{
long long cnt=n;
for(long long i=2; i*i<=n; i++)
{
if(n%i==0)
{
cnt-=cnt/i;
while(n%i==0)
n/=i;
}
}
if(n>1)
cnt-=cnt/n;
return cnt;
}
int main()
{
long long n,x;
while(~scanf("%lld",&n))
{
printf("%lld\n",f(n));
}
}