zoukankan      html  css  js  c++  java
  • 【洛谷P4139】上帝与集合的正确用法【扩展欧拉定理】

    题目大意:

    题目链接:https://www.luogu.org/problem/P4139
    给出pp,求222...mod p2^{2^{2^{...}}} mod p


    思路:

    根据欧拉定理,有
    apap mod φ(p)+φ(p) (mod p)a^pequiv a^{p mod varphi(p)+varphi(p)} (mod p)
    在这道题中,我们令q=222...q=2^{2^{2^{...}}},那么题目就转变为了求2q mod p2^q mod p
    然后利用欧拉定理,所求即为2q mod φ(q)+φ(q)(modp)2^{q mod varphi(q)+varphi(q)}(mod p)
    其中q mod φ(q)q mod varphi(q)即为222...mod φ(q)2^{2^{2^{...}}}mod varphi(q),递归继续求解即可。直到q=1q=1时,答案即为0。
    每次用快速幂求出答案,phiphi是可以用线性筛预处理的。
    时间复杂度近似O(p)O(p)


    代码:

    #include <cstdio>
    using namespace std;
    typedef long long ll;
    
    const int N=10000010;
    int T,p,m,prime[N],v[N],phi[N];
    
    void euler(int n)  //预处理phi
    {
    	for (int i=2;i<=n;i++)
    	{
    		if (!v[i]) prime[++m]=i,v[i]=i,phi[i]=i-1;
    		for (int j=1;j<=m;j++)
    		{
    			if (prime[j]>v[i] || prime[j]>n/i) break;
    			v[i*prime[j]]=prime[j];
    			if (i%prime[j]) phi[i*prime[j]]=phi[i]*(prime[j]-1);
    				else phi[i*prime[j]]=phi[i]*prime[j];
    		}
    	}
    }
    
    ll power(ll x,ll mod,ll k)  //快速幂
    {
    	ll ans=1;
    	for (;k;k>>=1,x=x*x%mod)
    		if (k&1) ans=ans*x%mod;
    	return ans;
    }
    
    ll solve(ll p)
    {
    	if (p==1) return 0;
    	return power(2,p,solve(phi[p])+phi[p]);
    }
    
    int main()
    {
    	euler(1e7);
    	scanf("%d",&T);
    	while (T--)
    	{
    		scanf("%d",&p);
    		printf("%lld
    ",solve((ll)p));
    	}
    	return 0;
    } 
    
  • 相关阅读:
    C#秘密武器之表达式树
    C#秘密武器之特性
    [转]拷贝构造函数详解
    [转]STL 容器一些底层机制
    C++ Qt多线程 TcpSocket服务器实例
    QByteArray储存二进制数据(包括结构体,自定义QT对象)
    [转]浅谈 C++ 中的 new/delete 和 new[]/delete[]
    [转]QList内存释放
    Subscribe的第四个参数用法
    ROS多线程订阅消息
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998069.html
Copyright © 2011-2022 走看看