• BZOJ 3884 上帝与集合的正确用法


    Description

    根据一些书上的记载,上帝的一次失败的创世经历是这样的:
    第一天, 上帝创造了一个世界的基本元素,称做“元”。
    第二天, 上帝创造了一个新的元素,称作“α”。“α”被定义为“元”构成的集合。容易发现,一共有两种不同的“α”。
    第三天, 上帝又创造了一个新的元素,称作“β”。“β”被定义为“α”构成的集合。容易发现,一共有四种不同的“β”。
    第四天, 上帝创造了新的元素“γ”,“γ”被定义为“β”的集合。显然,一共会有16种不同的“γ”。
    如果按照这样下去,上帝创造的第四种元素将会有65536种,第五种元素将会有2^65536种。这将会是一个天文数字。
    然而,上帝并没有预料到元素种类数的增长是如此的迅速。他想要让世界的元素丰富起来,因此,日复一日,年复一年,他重复地创造着新的元素……
    然而不久,当上帝创造出最后一种元素“θ”时,他发现这世界的元素实在是太多了,以致于世界的容量不足,无法承受。因此在这一天,上帝毁灭了世界。
    至今,上帝仍记得那次失败的创世经历,现在他想问问你,他最后一次创造的元素“θ”一共有多少种?
    上帝觉得这个数字可能过于巨大而无法表示出来,因此你只需要回答这个数对p取模后的值即可。
    你可以认为上帝从“α”到“θ”一共创造了10^9次元素,或10^18次,或者干脆∞次。
    一句话题意:

     

    Input

    接下来T行,每行一个正整数p,代表你需要取模的值

    Output

    T行,每行一个正整数,为答案对p取模后的值

    Sample Input

    3
    2
    3
    6

    Sample Output

    0
    1
    4

    HINT

    对于100%的数据,T<=1000,p<=10^7
    拓展欧拉定理(降幂大 Fa♂),当b>=Φ(p)时
    ab=ab%Φ(p)+Φ(p)
    所以不断递归,直到Φ(p)<=2,则直接算出aΦ(p)(因为b%Φ(p)总是0)
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 typedef long long lol;
     8 const int N=1e7;
     9 lol ans;
    10 int prime[N+5],phi[N+5],tot;
    11 bool vis[N+5];
    12 void pre()
    13 {int i,j;
    14   phi[1]=0;
    15   for (i=2;i<=N;i++)
    16     {
    17       if (vis[i]==0)
    18     {
    19       ++tot;
    20       prime[tot]=i;
    21       phi[i]=i-1;
    22     }
    23       for (j=1;j<=tot;j++)
    24     {
    25       if (1ll*i*prime[j]>N) break;
    26       vis[i*prime[j]]=1;
    27       if (i%prime[j]==0)
    28         {
    29           phi[i*prime[j]]=phi[i]*prime[j];
    30           break;
    31         }
    32       else  phi[i*prime[j]]=phi[i]*(prime[j]-1);
    33     }
    34     }
    35 }
    36 lol qpow(lol x,lol y,lol p)
    37 {
    38   lol res=1;
    39   while (y)
    40     {
    41       if (y&1) res=res*x%p;
    42       x=x*x%p;
    43       y/=2;
    44     }
    45   return res;
    46 }
    47 lol f(lol p)
    48 {
    49   if (phi[p]<=2) return qpow(2,phi[p],p);
    50   return qpow(2,f(phi[p])+phi[p],p);
    51 }
    52 int main()
    53 {lol p;
    54   int T;
    55   pre();
    56   cin>>T;
    57   while (T--)
    58     {
    59       scanf("%lld",&p);
    60       ans=qpow(2,f(phi[p])+phi[p],p);
    61       printf("%lld
    ",ans);
    62     }
    63 }
  • 相关阅读:
    使用FileReader在浏览器读取预览文件(image和txt)
    移动端Vue图片获取,压缩,预览组件-upload-img(H5+获取照片,压缩,预览)
    文件(图片)转base64
    Vue单页面应用打包app处理返回按钮
    hbuilder/hbuilderx 无法检测到模拟器
    不启动AndroidStudio直接启动其模拟器
    ES6,箭头函数 (=>)注意点
    ES6,扩展运算符
    strcmp使用注意
    android11 gc5035前置摄像头当作后置使用左右镜像问题
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8301833.html
Copyright © 2020-2023  润新知