码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-09-11 12:28:01      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:题解   集合   map   scan   tar   code   std   ace   class   

学习借鉴了skywalkert大佬的题解 Orz

首先题目需要用到欧拉函数的一个性质

$\forall x\geq \phi(p)$

$a^x\equiv a^{x \; mod \; \phi(p) + \phi(p)}(mod\;p)$

设$f(p) = 2^{2^{2^{...}}}mod \; p$

$f(p)=2^{(2^{2^{...}} mod \; \phi(p)) + \phi(p)}mod \; p \\=2^{f(\phi(p)) + \phi(p)} mod \; p$

关于f(p)的递推式知道了,只要dfs就可以了。

时间复杂度$O(\sqrt{p}logp)$

map的作用就是记录取模x的时候的值

#include <cstdio>
#include <map>
using namespace std;

map<int,int>vis;

int pow(int x,int k,int p){
    int ans = 1;
    while(k){
        if(k&1) ans=(long long )ans*x%p;
        x = (long long)x * x % p;
        k>>=1;
    }
    return ans;
}

int phi(int x){
    int ans = x;
    for(int i=2;i*i<=x;i++){
        if(x%i==0){
            ans -= ans/i;
            while(x%i==0) x/=i;
        }
    }
    if(x>1) ans -= ans/x;
    return ans;
}

int dfs(int x){
    if(vis.count(x)) return vis[x];
    int p = phi(x);
    return vis[x] = pow(2,dfs(p)+p,x);
}

int main(){
    int t,n;
    scanf("%d",&t);
    vis[1]=0;
    while(t--){
        scanf("%d",&n);
        printf("%d\n",dfs(n));
    }
    return 0;
}

 

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

标签:题解   集合   map   scan   tar   code   std   ace   class   

原文地址:http://www.cnblogs.com/OIerLYF/p/7504243.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!