zoukankan      html  css  js  c++  java
  • 洛谷 P4139 上帝与集合的正确用法 解题报告

    P4139 上帝与集合的正确用法

    题目描述

    根据一些书上的记载,上帝的一次失败的创世经历是这样的:

    第一天, 上帝创造了一个世界的基本元素,称做“元”。

    第二天, 上帝创造了一个新的元素,称作“α”。“α”被定义为“元”构成的集合。容易发现,一共有两种不同的“α”。

    第三天, 上帝又创造了一个新的元素,称作“β”。“β”被定义为“α”构成的集合。容易发现,一共有四种不同的“β”。

    第四天, 上帝创造了新的元素“γ”,“γ”被定义为“β”的集合。显然,一共会有16种不同的“γ”。

    如果按照这样下去,上帝创造的第四种元素将会有65536种,第五种元素将会有2^65536种。这将会是一个天文数字。

    然而,上帝并没有预料到元素种类数的增长是如此的迅速。他想要让世界的元素丰富起来,因此,日复一日,年复一年,他重复地创造着新的元素……

    然而不久,当上帝创造出最后一种元素“θ”时,他发现这世界的元素实在是太多了,以致于世界的容量不足,无法承受。因此在这一天,上帝毁灭了世界。

    至今,上帝仍记得那次失败的创世经历,现在他想问问你,他最后一次创造的元素“θ”一共有多少种?

    上帝觉得这个数字可能过于巨大而无法表示出来,因此你只需要回答这个数对p取模后的值即可。

    你可以认为上帝从“α”到“θ”一共创造了(10^9)次元素,或(10^{18})次,或者干脆∞次。

    一句话题意:(2^{2^{2^{dots}}}mod p)

    输入输出格式

    输入格式:

    第一行一个整数(T),表示数据个数。

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

    输出格式:

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

    说明

    对于100%的数据,(Tle 1000,p le 10^7)


    其实就是裸到扩展欧拉定理

    先把(varphi(1-1e7))筛出来

    然后递归进去求,直到某一项为0,再快速幂回来

    复杂度大概是两个log的?

    扩展欧拉定理

    [ a^b= egin{cases} a^{b mod varphi(p)},(a,p)=1 \ a^b,(a,p) ot=1,b<varphi(p) \ a^{b mod varphi(p)+varphi(p)},(a,p) ot=1,b ge varphi(p) end{cases} mod p ]


    Code:

    #include <cstdio>
    #define ll long long
    const int N=1e7;
    int phi[N+10],v[N+10],pri[N+10],is_pri[N+10],cnt;
    void Euler()
    {
        for(int i=2;i<=N;i++)
        {
            if(!is_pri[i])
            {
                v[i]=i;
                phi[i]=i-1;
                pri[++cnt]=i;
            }
            for(int j=1;j<=cnt&&i*pri[j]<=N;j++)
            {
                if(pri[j]>v[i]) break;
                is_pri[pri[j]*i]=1;
                v[pri[j]*i]=pri[j];
                phi[pri[j]*i]=phi[i]*(i%pri[j]?pri[j]-1:pri[j]);
            }
        }
    }
    ll quickpow(ll d,ll k,ll p)
    {
        ll f=1;
        while(k)
        {
            if(k&1) f=f*d%p;
            d=d*d%p;
            k>>=1;
        }
        return f;
    }
    ll dfs(int p)
    {
        if(p==2) return 0;
        return quickpow(2,dfs(phi[p])%phi[p]+(p&1?0:phi[p]),p);
    }
    int main()
    {
        Euler();
        ll t,p;
        scanf("%lld",&t);
        while(t--)
        {
            scanf("%lld",&p);
            printf("%lld
    ",dfs(p));
        }
        return 0;
    }
    
    

    2018.9.7

  • 相关阅读:
    python simplejson and json 使用及区别
    python 网页抓取并保存图片
    word2vec剖析,资料整理备存
    centos 安装LAMP环境后装phpmyadmin
    centos 安装卸载软件命令 & yum安装LAMP环境
    Ubuntu终端快捷键使用
    Ubuntu终端文件的压缩和解压缩命令
    文本预处理去除标点符号
    朴素贝叶斯分类器的应用
    Win32环境下代码注入与API钩子的实现(转)
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9603366.html
Copyright © 2011-2022 走看看