洛谷-4139 上帝与集合的正确用法

本文介绍了一种利用递归欧拉降幂算法解决特定数学问题的方法,该问题涉及高次幂运算的模运算。文章详细阐述了算法原理,包括如何通过递归方式降低指数,直至达到可以直接计算结果的状态。同时,提供了C++代码实现,帮助读者理解算法的具体应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述
一句话题意:
222… mod p2^{2^{2^{\dots}}}\bmod p222modp
输入格式
第一行一个整数T,表示数据个数。
接下来T行,每行一个正整数p,代表你需要取模的值
输出格式
T行,每行一个正整数,为答案对p取模后的值

输入输出样例
输入 #1
3
2
3
6

输出 #1
0
1
4

说明/提示
对于100%的数据,T≤1000,p≤107T\le 1000,p \le 10^7T1000,p107

解释:很明显递归欧拉降幂,na mod m=na mod Φ(m)+Φ(m) mod m,m>Φ(m)时n^a \bmod m=n^{a \bmod \Phi(m)+ \Phi(m)} \bmod m,m>\Phi(m)时namodm=namodΦ(m)+Φ(m)modm,m>Φ(m)
这里我们递归递归进行,直到a mod Φ(m)=0a \bmod \Phi(m)=0amodΦ(m)=0 就可以出结果

#include<iostream>
#define ll long long
using namespace std;
ll ou(ll n){
	ll ret=n;
	for(int i=2;i*i<=n;i++){
		if(n%i==0){
			ret=ret-ret/i;
			while(n%i==0) n/=i;
		}
	}
	if(n!=1) ret=ret-ret/n;
	return ret;
}
ll pow(ll a,ll b,ll mod){
	ll ret=1;
	while(b){
		if(b&1) ret=ret*a%mod;
		b>>=1;a=a*a%mod;
	}
	return ret;
}
bool check(ll x){
	int sum=0;
	while(x){
		if(x&1) sum++;
		x>>=1;
	}
	return sum==1;
}
ll ok(ll mod){
	if(check(mod)) return 0;
	ll sum=ou(mod);
	return pow(2,ok(sum)+sum,mod);
}
int T=0;
int main(){
	cin>>T;
	while(T--){
		ll n;cin>>n;
		cout<<ok(n)<<endl;
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值