[bzoj3884] 上帝与集合的正确用法
题意:要你算这个玩意额:222...222...
题解:
欧拉定理+递归
设p=2k∗q(q为奇数)
题目要求222...modp
变形为2k(222...−kmodq) (这里需要在草稿纸上算一下)
由于q是个奇数,那么肯定与2的指数互质
原式变为2k(2(22...−k)modϕ(q)modq)
然后就可以递归求解了,当模数为1的时候,递归就结束了,然后就可以回溯计算了
递归次数不超过log2p ,单次求ϕ(p)的复杂度为√p
所以总复杂度为T∗log2p∗√p
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
int gi() {
int x=0,o=1; char ch=getchar();
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') o=-1,ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return o*x;
}
int get_phi(int x) {
int ret=x;
for(int i=2; i*i<=x; i++) {
if(x%i==0) {
ret=ret/i*(i-1);
while(x%i==0) x/=i;
}
}
if(x>1) ret=ret/x*(x-1);
return ret;
}
int qpow(ll x, int y, int mo) {
ll ret=1;
while(y) {
if(y&1) ret=ret*x%mo;
x=x*x%mo,y>>=1;
}
return ret;
}
int solve(int p) {
if(p==1) return 0;
int k=0,phi,ret;
while(!(p&1)) p>>=1,k++;//while(p是个偶数)
phi=get_phi(p);
ret=solve(phi);
(ret+=phi-k%phi)%=phi;
ret=qpow(2,ret,p)%p;
return ret<<k;
}
int main() {
int T=gi();
while(T--) {
int p=gi();
printf("%d\n", solve(p));
}
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!