• [HAOI2012]外星人


    题目大意:
      告诉你一个数n,求满足φ^x(n)=1的x。

    思路:
      首先我们可以发现满足φ(n)=1的数只有2,也就是说你得到最终的结果,最后一步肯定是φ(2)。
      同时,可以发现φ(φ(2^k))=φ(2^(k-1)),因为1~2^k中间有且仅有奇数与2^k互质,个数是2^(k-1)个。
      φ是个积性函数,也就是说φ(n)=φ(p1^q1)*φ(p2^q2)*...*φ(pm^qm)。
      对于只有一种质因数的n, φ(n)=φ(p^q)=p^q*(1-1/p)=(p-1)*(p^q-1)。
      因此我们可以发现,每次φ下去的时候都会往里面加若干个质因数2,而对于偶数,每次会消掉一个质因数2。
      由于我们最后得到答案都要经过φ(2),原问题转化为可以消掉多少个2,也就是总共会产生多少个2。
      预处理出每个质因数最后能分解出多少个2,累加起来就是总共要消灭的2的个数。
      预处理的时候可以用类似于线性筛的方法做。
      注意如果一开始就没有质因数2,那就要多花一步来得到一个2。

     1 #include<cstdio>
     2 #include<cctype>
     3 typedef long long int64;
     4 inline int getint() {
     5     register char ch;
     6     while(!isdigit(ch=getchar()));
     7     register int x=ch^'0';
     8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     9     return x;
    10 }
    11 const int P=100001,N=9592;
    12 int f[P],prime[N],cnt;
    13 inline void pret() {
    14     f[1]=1;
    15     for(register int i=2;i<P;i++) {
    16         if(!f[i]) {
    17             prime[cnt++]=i;
    18             f[i]=f[i-1];
    19         }
    20         for(register int j=0;j<cnt;j++) {
    21             if(i*prime[j]>=P) break;
    22             f[i*prime[j]]=f[i]+f[prime[j]];
    23             if(!(i%prime[j])) break;
    24         }
    25     }
    26 }
    27 int main() {
    28     pret();
    29     for(register int T=getint();T;T--) {
    30         int64 ans=1;
    31         for(register int m=getint();m;m--) {
    32             const int p=getint(),q=getint();
    33             ans+=(int64)f[p]*q;
    34             if(p==2) ans--;
    35         }
    36         printf("%lld
    ",ans);
    37     }
    38     return 0;
    39 }
  • 相关阅读:
    DHCP协议详解(硬件方面原理)
    ASP.NET安全认证
    JAVA打包成.jar可运行项目
    JAVA菜单事件
    JAVA事件概述
    JAVA对话框事件
    各种事件汇聚
    把原来可空的列变成主键
    搜索模式中的所有表
    JAVA选项事件
  • 原文地址:https://www.cnblogs.com/skylee03/p/7735229.html
Copyright © 2020-2023  润新知