COGS2531. [HZOI 2016]函数的美 打表+欧拉函数

题目:http://cogs.pw/cogs/problem/problem.php?pid=2533

这道题考察打表观察规律。

发现对f的定义实际是递归式的

    f(n,k) = f(0,f(n-1,k))

    f(0,k) = balabalabalabala

    所以,实际上的f(n,k)是这么个东西

       f(0,(0,(0,(0,(0,(0,(0,(0,k))))))))

直接递归求解并打出表来,我们可以发现这样的事实

f(0,k) = k+1

所以有f(n,k) = n + k + 1;

所以题目就转化为了求n+k+1的欧拉函数,直接O(sqrt(n))解决

严谨的数学证明:

但是这道题其实本人认为最恰当的做法就是打表观察规律

仔仔细细的证明推式子有些得不偿失

 1 #include <cmath>
 2 #include <queue>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <iostream>
 6 #include <algorithm>
 7 using namespace std;
 8 typedef long long ll;
 9 inline void read(ll &x){
10     x=0;char ch;bool flag = false;
11     while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
12     while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
13 }
14 inline ll cat_max(const ll &a,const ll &b){return a>b ? a:b;}
15 inline ll cat_min(const ll &a,const ll &b){return a<b ? a:b;}
16 inline ll phi(ll x){
17     ll ret = x;
18     for(ll i=2;i*i<=x;++i){
19         if(x % i == 0){
20             ret /= i;ret *= (i-1);
21             while(x % i == 0) x /= i;
22         }
23     }
24     if(x^1) ret /= x,ret *= (x-1);
25     return ret;
26 }
27 int main(){
28     freopen("skyfuc.in","r",stdin);
29     freopen("skyfuc.out","w",stdout);
30     ll n,x;
31     while(scanf("%lld%lld",&n,&x) != EOF) 
32         printf("%lld\n",phi(n+x+1));
33     getchar();getchar();
34     return 0;
35 }

 

posted @ 2016-11-09 16:35  Sky_miner  阅读(392)  评论(0编辑  收藏  举报