zoukankan      html  css  js  c++  java
  • bzoj 3884 上帝与集合的正确用法(递归,欧拉函数)

    【题目链接】

        http://www.lydsy.com/JudgeOnline/problem.php?id=3884

    【题意】

        求2^2^2… mod p

    【思路】

        设p=2^k * q+(1/0),使q为一个奇数

      第二项如果是1,mod 1 为0可以忽略。

        则我们求:

            2^2^2… mod p

           =2^k*(2^(2^2…-k) mod q)

        因为q是奇数所以与2互质,根据欧拉定理:

            a^phi(p) mod p=1,(a,p)=1

        转化为:

            2^k*(2^(2^2…mod phi(p) – k mod phi(p)))

        对于前一项可以递归求解,子问题为solve(phi(p)),递归边界为p=1,此时返回0。

    【代码】

     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 
     6 typedef long long ll;
     7 const int N =  1e5+10;
     8 
     9 ll pow(ll a,ll p,ll mod)
    10 {
    11     ll ans=1;
    12     while(p) 
    13     {
    14         if(p&1) ans=(ans*a)%mod;
    15         a=(a*a)%mod; p>>=1;
    16     }
    17     return ans;
    18 }
    19 ll phi(ll x)
    20 {
    21     ll ans=x;
    22     for(int i=2;i*i<=x;i++) if(x%i==0)
    23     {
    24         ans=ans/i*(i-1);
    25         while(x%i==0) x/=i;
    26     }
    27     if(x>1) ans=ans/x*(x-1);
    28     return ans;
    29 }
    30 
    31 int n,T,P;
    32 
    33 ll solve(ll p)
    34 {
    35     if(p==1) return 0;
    36     int k=0;
    37     while(~p&1) p>>=1,k++;
    38     ll pi=phi(p);
    39     ll ans=solve(pi);
    40     ans=(ans+pi-k%pi)%pi;
    41     ans=pow(2,ans,p)%p;
    42     return ans<<k;
    43 }
    44 
    45 int main()
    46 {
    47     scanf("%d",&T);
    48     while(T--)
    49     {
    50         scanf("%d",&P);
    51         printf("%lld
    ",solve(P));
    52     }
    53     return 0;
    54 }

    P.S.题解抄的PoPoQQQ的,自己又叙述了一遍而已

  • 相关阅读:
    移动网络优化
    移动网络架构与数据传输
    移动网络简介与RRC
    CSS之外边距折叠
    网络协议之TLS
    Smarty 模板引擎简介
    FormData介绍
    相对路径与绝对路径
    OAuth2.0
    Redis学习手册(List数据类型)
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5340210.html
Copyright © 2011-2022 走看看